I have a hierarchical DbContext structure, where I would like a specialized DbContext with its own DbSets to inherit the DbSets of a BaseDbContext.
While accessing the underlying ObjectContext with ((IObjectContextAdapter)this).ObjectContext it takes too long (several minutes) to receive the ObjectContext.
Is there an issue with DbContext in CT5, that getting an ObjectContext from derived DbContext is not performantly possible?
The structure is: DbContext(EF4) -> myBaseDbContext -> mySpecializedDbContext.
Does anyone have an idea of what´s going on in this scenario?
It´s just POCO (CF) with TPC and a little inheritance.
I didn't have performance issues with following and you don't have so many DbSets:
public class MyContext: DbContext
{
//your DbSets<> and other
public ObjectContext ObjectContext()
{
return (this as IObjectContextAdapter).ObjectContext;
}
}
Related
I am implementing a repository pattern. My main reasons for this:
To abstract client code away from persistence specifics (Entity Framework)
To support testability
Generic Repository or not?
The issue I have run into is whether I should have a generic repository or not. An IQueryable<T> Query() method would provide the calling code with means to construct specific queries. The issue here is that this is leaky abstraction - Entity Framework specifics are now leaking into my client code.
How would this effect unit testing? Would I still be able to Mock the ICustomerRepository with this implementation?
How would this effect swopping out my persistence layer? Like Azure Storage Tables or NHibernate.
Otherwise I would have to implement very specific query method on ICustomerRepository, such as GetIsActiveByFirstName() and GetIsActiveByDistrict(). I dislike this a lot as my repository classes are going to become jam-packed with different query methods. This system has hundreds of models and so there could be hundreds or even thousands of these methods to write and maintain.
You can have a relatively clean IRepository<T> by sticking to the pattern.
Data Access LAyer
reference to EF and Core project
Has Respository<T> : IRepository<T>
Option has IEFJunk declaration (Only if using multiple repositories)
Reference to Core
Respository is injected with Context (typically during instantiation)
Core
Interfaces that can be "Injected"
IRepository declaration. With no EF data type use.
NO reference to EF
So now code in Core you can refer to an IRepository<t>.
The implementing class can have EF specifics. But this can not be accessed from core!
so you can have IQueryable.
public interface IRepositoryBase<TPoco>{
IQueryable<TPoco> GetListQ(Expression<Func<TPoco, bool>> predicate);
//...
BUt if you decided you wanted to add
//...
// logically exposing IQueryable<T> Include<T>(this IQueryable<T> source, string path) from EF
IQueryable<TPoco> IncludeNAVProp(string navToInclude);
}
Then the Repository implementation
return Context.Set<TPoco>().Include(navToInclude);
requires the underlying provider to be EF. So now mocking is against an actual EF provider.
And unless you are careful, EF specific code. leaks out.
Indeed the interface IRepository that has the CONCEPT "include" can already be considered LEAKY.
Keeping EF specifics out of your Interfaces, is the key to avoiding the leaks.
And you can have 1 IRepository<t> and 1 Respository<t> and support 100s of tables
Some background: We sell an online product and each customer gets their own database but are using a shared service.
I would like to use EF6 instead of old ADO.NET, But as far as I know it's not possible to change the database when the dbcontext is created, and i fear that it's too expensive to create a new dbcontext for each query.
And caching 1000+ dbcontext's sounds like a very bad solution.
Connection pooling will not work well with 1000+ connection strings. There will be one pool for each database resulting in an enormous amount of connections.
I recommend that you connect to a dummy database first, then use DbConnection.ChangeDatabase to change into the right database. EF does not notice that and works just fine.
You don't need to cache DbContext's. They are lightweight.
This is actually pretty easy to do
public class MyContext : DbContext{
public MyContext(string connectionStringName): base(connectionStringName){}
}
or
public class MyContext : DbContext{
public MyContext(DbConnection connection): base(connection, contextOwnsConnection: true){}
}
You should not be too concerned about the cost of construction of DbContext. There are other factors to consider in deciding the lifetime of your DbContext/ObjectContext, which you can find here.
It's not a good idea to share your DbContext instance primarily because of Memory Usage and Thread Safety as mentioned in the above link.
You can do next:
public class BaseContext<TContext> : DbContext where TContext : DbContext
{
protected BaseContext(): base("name=DbName")
{
}
}
And that use it like this:
public class StatusContext : BaseContext<StatusContext>
{
....
}
All contexts that inherit from BaseContext will use same db.
I am currently finalizing the architecture of my new application that will be using Entity Framework as its ORM. However, I am a little bit confused with respect to whether I should go with the default option (DbSet and DbContext), or use a "tricky" option (ObjectSet and ObjectContext)? Do the latter classes offer advantages over the default classes?
There are several posts on this topic which go into detail about your question, and I'm sure you will find helpful:
On DbContext, is it strictly better than ObjectContext?
entity framework 4.1 objectContext vs dbContext
ObjectContext vs DbContext
difference between DBContext and Object context in Entity Framework
Just summarization. DbContext is a wrapper around the ObjectContext. You can also access ObjectContext by DbContext if you need. ObjectContext came with EF4 and DbContext with EF4.1. Basically both contexts are almost same. DbContext simplifies many things. Moreover DbContext doesn't contains hundreds of properties like ObjectContext - it is more clear and compact.
I have a legacy EF 4 library with a database-first generated ObjectContext with EntityObjects. I'd like to slowly migrate to using DbContext and am in need of some guidence.
One of the overloads for DbContext takes an existing ObjectContext. I thought this would allow me to wrap my existing ObjectContext in a DbContext and expose my existing EntityObjects through IDbSet properties. Unfortunately, when creating the DbContext, the IDbSet properties are not created and instead an exception is thrown with a message of: "Verify that the type was defined as a class, is not primitive, nested or generic, and does not inherit from EntityObject."
Is there no way to use a DbContext with IDbSet exposing an existing ObjectContext and EntityObjects? It seems strange that I can create a DbContext with an ObjectContext, but not expose the entities themselves.
Here's some sample code:
public class MyDbContext : DbContext
{
public MyDbContext(MyObjectContext objectContext, bool dbContextOwnsObjectContext)
: base(objectContext, dbContextOwnsObjectContext)
{
}
public IDbSet<Person> People { get; set; }
}
The exception is caused by the DbContext trying to create the IDbSet. Person is an EntityObject from my existing EDMX.
As you noted, you cannot use the existing entity objects that the edmx created.
Have you considered using the Reverse Engineer Code First power tools?
I've used them in several projects, and its simple as pointing it at your database, it generates the model in the same project, and then removing the edmx file.
Why are we able to use automatic properties with DBSet, but not with ObjectSet:
public class SomeContext : DbContext
{
public DbSet<Address> Addresses { get; set; }
...
}
Thank you
DbContext is using convention over configuration paradigm. It discovers entity sets based on DbSet properties defined on the DbContext derived class (or in general, it discovers your model based on your code). ObjectContext does not do any discovery and is not convention based. It just reads your model from csdl, ssdl and msl artifacts. As a result ObjectContext requires that the user tells exactly what needs to be exposed.
Simply because DbContext API is newer version created to provide simplified API for better development experience.