Entity Framework Table Per Type Performance

 ̄綄美尐妖づ 提交于 2019-12-04 05:15:40

We've hit this same problem and are considering porting our DAL from EF4 to LLBLGen because of this.

In the meantime, we've used compiled queries to alleviate some of the pain:

Compiled Queries (LINQ to Entities)

This strategy doesn't prevent the mammoth queries, but the time it takes to generate the query (which can be huge) is only done once.

You'll can use compiled queries with Includes() as such:

static readonly Func<AdventureWorksEntities, int, Subcomponent> subcomponentWithDetailsCompiledQuery = CompiledQuery.Compile<AdventureWorksEntities, int, Subcomponent>(
       (ctx, id) => ctx.Subcomponents
            .Include("SubcomponentType")
            .Include("A.B.C.D")
            .FirstOrDefault(s => s.Id == id));

    public Subcomponent GetSubcomponentWithDetails(int id)
    {
        return subcomponentWithDetailsCompiledQuery.Invoke(ObjectContext, id);
    }

This seems a bit confused. You're talking about TPH, but when you say:

The way I see it, I should be able to add a reference to a Stored Procedure from within EF (probably using EFExtensions) that has the the TSQL that selects only the fields I need, even using the code generated by EF for the monster UNION/JOIN inside the SP would prevent the SQL being generated every time a call is made - not something I would intend to do, but you get the idea.

Well, that's Table per Concrete Class mapping (using a proc rather than a table, but still, the mapping is TPC...). The EF supports TPC, but the designer doesn't. You can do it in code-first if you get the CTP.

Your preferred solution of using a proc will cause performance problems if you restrict queries, like this:

var q = from c in Context.SomeChild
        where c.SomeAssociation.Foo == foo
        select c;

The DB optimizer can't see through the proc implementation, so you get a full scan of the results.

So before you tell yourself that this will fix your results, double-check that assumption.

Note that you can always specify custom SQL for any mapping strategy with ObjectContext.ExecuteStoreQuery.

However, before you do any of this, consider that, as RPM1984 points out, your design seems to overuse inheritance. I like this quote from NHibernate in Action

[A]sk yourself whether it might be better to remodel inheritance as delegation in the object model. Complex inheritance is often best avoided for all sorts of reasons unrelated to persistence or ORM. [Your ORM] acts as a buffer between the object and relational models, but that doesn't mean you can completely ignore persistence concerns when designing your object model.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!