Can I get at the DbContext created by LinqPad? - entity-framework

I am trying to test my IRepository interface via linqpad. To make one I have a constructor that looks like this:
IRepository dataAccess = new GenericRepository(dbContext);
This works fine in my own code, but I don't know how to get at the dbContext in linqpad. (I would rather not create my own if I don't have to.
All my code uses IRepository (so that I can unit test). I can't test it in LinqPad unless I can make a GenericRepository using the dbContext.
Any idea how I can get at the DbContext that LinqPad creates?

I just needed to set the connection to my EF Connection. After that I could use the this keyword and it worked.

Related

Am I properly creating my interface for a partial DbContext class in EF6?

I am utilizing ASP.NET WebAPI 2 & EF6 for a very small project which utilizes AutoFac to inject my DbContext directly into my controllers. I am not using a repository pattern as per Ryan's answer here: NOT using repository pattern, use the ORM as is (EF). To perform the injection, I went ahead and created an interface like so:
public interface IMoveGroupEntities : IDisposable
{
System.Data.Entity.DbSet<HostEntry> HostEntries { get; set; }
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
Task<int> SaveChangesAsync();
}
Then implemented the interface on a partial class which sits in conjunction with my generated entities like so:
public partial class MoveGroupEntities : IMoveGroupEntities
{
}
I have a sneaking suspicion I'm doing something incorrectly here as I feel like this line:
DbEntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
Shouldn't be needed, but it does appear to be necessary as "Entry" is used from within my scaffolded API controller.
Can anyone chime in here on a better way to achieve this?
The best you can say about scaffolded code is: it works. It's not the best code architecturally. I fully agree with the link you quote, but that doesn't mean that the controllers should be in touch with EF artifacts directly (including Entry).
I think it's a mistake to replace one DbSet wrapper (repository) by another wrapper. The gist of the answer is: use the context (and DbSets, etc.) directly in your code. That is: don't use wrappers. That is not: use contexts (etc.) anywhere. You're doing the exact opposite: you create a different type of wrapper in order to use EF anywhere. But it's a good thing that your gut feeling doesn't really like it.
I always prefer to keep action methods (MVC, Web API) small. Basically, I just make them call a service method. It's the service that deals with contexts and everything EF has to offer. These services may be in a separate assembly, but wherever they are, they are injected into the controllers by dependency injection and, likewise, they obtain their contexts by DI.

Is there a GetObjectType in DbContext?

I'm using POCO proxies and I'd like to get the type of a object. I've found a few examples using GetObjectType for ObjectContext but I'm using DbContext and I don't see it there. Is this something I need to add to my repository class so it can have access to the DbContext? Or am I completely wrong? Thanks
There is a static method ObjectContext.GetObjectType which, of course, you can use anywhere where System.Data.Objects is in scope. You don't need a DbContext instance.

How to implement IDbContextFactory for use with Entity Framework data migrations

I am trying to use Entity Framework data migrations, as described in this post.
However, when I try to execute the Enable-Migrations step, I receive the following error in Package Manager Console:
The target context 'MyDataContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory
So, I created a factory class that implements IDbContextFactory in the project that contains my DbContext class, but data migrations doesn't appear to recognize it.
Is there something that I should explicitly do to instruct data migrations to use this factory class?
I also hit this problem as i wrote my context to take a connection string name (and then used ninject to provide it).
The process you've gone through seems correct, here is a snippet of my class implementation if it's of any help:
public class MigrationsContextFactory : IDbContextFactory<MyContext>
{
public MyContext Create()
{
return new MyDBContext("connectionStringName");
}
}
That should be all you need.
Like #Soren pointed out, instead of using IDbContextFactory, not supported on some earlier EF Core releases (i.e. EF Core 2.1), we can implement IDesignTimeDbContextFactory<TContext>, which supports the missing ConnectionString parameter.
For a settings.json based aproach, which you can use with either of the referred interfaces, check #Arayn's sample which allows us to define "ConnectionStrings:DefaultConnection" value path
Update 1
According to #PaulWaldman's comment, on EF Core 5 support for IDbContextFactory was reintroduced. For further details, check his comment below.

How do I pass a connection string to the constructor of a database-first DBContext with Entity Framework 4.1?

For various reasons I would like to not store the connection string for my Entity Framework DB model in one of the various .config files. (I am using the latest and greatest DBContext API with the new Entity Framework version 4.1, .NET 4 and Visual Studio 2010 C#.) However, the code generation template for DBContext only creates a single parameterless constructor. (If I don't use the DBContext API, then my entity framework model has 7 different constructors to chose from, including the one I want.)
The only way I could figure out how to do this was to directly modify the code-generation template (context.tt file) to give me the constructor I want (example code below). This works, but it feels like I'm doing it "the hard way". What is the correct way to get a DBContext constructor that accepts a connection string?
public <#=Code.Escape(container)#>(string connectionString)
: base(connectionString)
{
<#
WriteLazyLoadingEnabled(container);
#>
}
One final note in case it might help somebody else. Although this method works, it took me a while to realize that the "connection string" is not strictly the DB connection string, but rather the special entity framework connection string which contains the DB connection string (just like what would be stored in the app.config file).
Your approach looks like the most correct way to do this. It's what the t4 templates were created for, and you're basically doing the same thing that the model-first templates do by default.
Another possibility would be to make the db context class be partial (if it isn't by default) and create another partial class file alongside it to add the constructor you want. But it seems likely that you'll want all of your t4-generated contexts to follow this pattern, so I think it's best to leverage the code generation to do this automatically the way you do in the question.

How to make ObjectContext private?

I've created a BLL which queries Entity Framework context. EDML file is in the same BLL assembly. It accepts EF entities as parameters from presentation layer and returns EF entities as results. To accomplish this I kept entities public so presentation layer can create them like DLL.TablName newRecord = new DLL.TableName() etc. The problem is with entities my objectcontext is exposed too since it's public. I can manually change it to private in designer generated code but if I make any changes to it it becomes public again. I didn't see any access modifier setting in the designer. How can I make ObjectContext private or internal?
I'm still in the layer design process so I can change my design if it can't be done.
You could probably inherit your Framework class and using the new keyword "hide" the ObjectContext like so:
public class DataContext : YourEFContext {
private new ObjectContext ObjectContext { get; }
}
I'm pretty sure you wanted something like this...