实体框架6 DBContext只包含所有表的子集

时间:2014-09-02 09:35:40

标签: c# .net sql-server entity-framework dbcontext

我们有一个包含770个表的庞大数据库,并希望使用EF 6.1x进行一些性能测试。

我们只想查询这770个表中的5个。是否可以创建一个只有5-6个实体/ DBSets的“轻”DBContext,而不是使用完整的770-tables-context?

当我们使用完整的上下文时,一个包含4个连接的简单查询需要45秒。那是44秒太长了。 我们正在使用代码优先(逆向工程)。

问题: 当我们创建完整上下文的这种“轻”版本(即仅5个表)时,EF抱怨所有与这5个表以某种方式相关的其他实体都缺少密钥。我们只映射这5个表的键,属性和关系,而不是其余的。

由于用LINQ编写的查询只查询5个表,因此EF应该忽略其他765个表,但不会。 为什么不呢? LazyLoading = true / false似乎与此无关。

注意:显然,可以在DB中创建一个视图,该视图使用LINQ查询执行我们在代码中所做的操作。问题是可以使用上面的“轻量级”DbContext来完成。

上下文的“轻”版本:

public class ItemLookupContext : DbContext
{
    static ItemLookupContext()
    {
        Database.SetInitializer<ItemLookupContext>( null );
    }

    public ItemLookupContext()
        : base( "Name=ItemLookupContext" )
    {
        //Configuration.LazyLoadingEnabled = true;
    }

    public DbSet<Identity> Identities { get; set; }
    public DbSet<Item> Items { get; set; }
    public DbSet<Price> Prices { get; set; }
    public DbSet<Department> Departments { get; set; }
    public DbSet<Brand> Brands { get; set; }

    protected override void OnModelCreating( DbModelBuilder modelBuilder )
    {
        modelBuilder.Configurations.Add( new IdentityMap() );
        modelBuilder.Configurations.Add( new ItemMap() );
        modelBuilder.Configurations.Add( new PriceMap() );
        modelBuilder.Configurations.Add( new DepartmentMap() );
        modelBuilder.Configurations.Add( new BrandMap() );

        //ignore certain entitities to speed up loading?
        //does not work
        modelBuilder.Ignore<...>();
        modelBuilder.Ignore<...>();
        modelBuilder.Ignore<...>();
        modelBuilder.Ignore<...>();
        modelBuilder.Ignore<...>();
    }
}

4 个答案:

答案 0 :(得分:6)

你尝试做什么像“Bounded Context”这样的DDD模式之一

因此,您可以查看Julie Lerman撰写的这篇文章,Shrink EF Models with DDD Bounded Contexts

答案 1 :(得分:4)

只需为您的表创建DBContext即可。为了防止Entity Framework对未映射的表抱怨,您可以在应用程序中关闭db初始化。把它放在你的global.asax / Startup.cs

Database.SetInitializer<YourDbContext>(null);

它告诉EF停止将您的实际数据库结构与DbContext进行比较。 这也意味着如果有人更改了您的EF映射表,您就没有机会收到有关该表的通知。

答案 2 :(得分:3)

当您在班级A和班级B之间建立多对一关系时:

public class A
{
   public B b {get; set;}
}
public class B
{
    public ICollection<A> As {get; set;} 
}

并定义以下DbContext,EF 自动包括DbSet<B>的{​​{1}}:

DbContext

因此,如果您希望自己的灯光public class MyContext : DbContext { ... public DbSet<A> As { get; set; } } 不包含相关的DbContext,只需使用DbSet方法:

Ignore

答案 3 :(得分:0)

看起来您使用了Entity Framework Power Tools之类的工具来生成实体类和映射。这将为数据库中的每个表生成一个类,一个巨大的上下文,所有这些类的映射和所有可能的关联。这太过分了。

首先删除您不需要的所有类和映射。然后删除所剩下的几个类中删除的所有关联, not 原始外键字段。同时从上下文中删除所有DbSet,除了你需要的几个。

这种精简的课堂模式本身就是一致的。它不会与数据库中的所有实体建立关联,但可以通过引用上下文之外的实体的外键值进行过滤。

如果您以任何其他方式生成/创建代码,这仍然是关键:仅使用导航属性到类模型中的其他类。对于其他引用,请使用原始外键属性。