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

时间:2022-09-15 09:31:27

We have a huge database with 770 tables and want to do some performance testing with EF 6.1x.

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

We want to query only 5 of those 770 tables. Is it possible to create a "light" DBContext with only 5-6 entities/DBSets instead of using the full 770-tables-context?

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

When we use the full context, a simple query with 4 joins takes 45 seconds. Thats' 44 seconds too long. We are using code-first (reverse engineered).

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

The problem: When we create such a "light" version of the full context (i.e. 5 tables only), EF complains that all the other entities that are somehow related to these 5 tables have missing keys. We only map the keys, properties, relationships for those 5 tables, but not the rest.

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

Since the query written in LINQ only queries 5 tables, EF should simply ignore the other 765 tables, but it won't. Why not? LazyLoading=true/false doesn't seem to have any bearing on this.

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

Note: Obviously one could create a view in the DB that does what we do in code with a LINQ query. The question is can it be done with a "light" DbContext as above.

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

There's the "light" version of the context:

有上下文的“轻”版本:

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 个解决方案

#1


5  

what you trying to something like "Bounded Context" which is one of DDD patterns

你试图做什么像“有界上下文”这样的DDD模式之一

So, you can check this article by Julie Lerman, Shrink EF Models with DDD Bounded Contexts

因此,您可以查看Julie Lerman撰写的文章,使用DDD有界上下文缩小EF模型

#2


2  

When you have a many-to-one relation between class A and class B:

当A类和B类之间存在多对一关系时:

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

and define following DbContext, EF automatically includes DbSet<B> to the DbContext:

并定义以下DbContext,EF自动将DbSet 包含到DbContext:

public class MyContext : DbContext
{
   ...
   public DbSet<A> As { get; set; }
}

So, if you want your light DbContext does not includes the related DbSets, simply use Ignore method:

所以,如果你想要你的光DbContext不包含相关的DbSet,只需使用Ignore方法:

public class MyContext : DbContext
{
   ...
   public DbSet<A> As { get; set; }

   protected override void OnModelCreating( DbModelBuilder modelBuilder )
   {
      modelBuilder.Ignore<B>();
   }
}

#3


2  

Simply just create your DBContext for your tables. To prevent Entity Framework moaning about the not mapped tables, you have switch off the db initialization in your application. Put this in your global.asax/Startup.cs

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

Database.SetInitializer<YourDbContext>(null);

It tells EF to stop comparing your actual DB structure against your DbContext. It also means that if someone changes your EF mapped tables, you have no chance of getting notified about that.

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

#4


0  

It looks like you used a tool like Entity Framework Power Tools to generate the entity classes and mappings. This would have generated a class for each table in the database, a huge context, mappings for all these classes and all possible associations. This is way too much.

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

First remove all classes and mappings that you don't need. Then remove all associations to removed classes in the few classes you have left, not the primitive foreign key fields. Also remove all DbSets from the context except the few you need.

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

This slimmed-down class model will be consistent in itself. It won't have associations to all entities in the database, but it will be possible to filter by foreign key values that refer to entities outside the context.

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

If you generated/created the code in any other way this is still the crux: only use navigation properties to other classes in the class model. For other references use primitive foreign key properties.

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

#1


5  

what you trying to something like "Bounded Context" which is one of DDD patterns

你试图做什么像“有界上下文”这样的DDD模式之一

So, you can check this article by Julie Lerman, Shrink EF Models with DDD Bounded Contexts

因此,您可以查看Julie Lerman撰写的文章,使用DDD有界上下文缩小EF模型

#2


2  

When you have a many-to-one relation between class A and class B:

当A类和B类之间存在多对一关系时:

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

and define following DbContext, EF automatically includes DbSet<B> to the DbContext:

并定义以下DbContext,EF自动将DbSet 包含到DbContext:

public class MyContext : DbContext
{
   ...
   public DbSet<A> As { get; set; }
}

So, if you want your light DbContext does not includes the related DbSets, simply use Ignore method:

所以,如果你想要你的光DbContext不包含相关的DbSet,只需使用Ignore方法:

public class MyContext : DbContext
{
   ...
   public DbSet<A> As { get; set; }

   protected override void OnModelCreating( DbModelBuilder modelBuilder )
   {
      modelBuilder.Ignore<B>();
   }
}

#3


2  

Simply just create your DBContext for your tables. To prevent Entity Framework moaning about the not mapped tables, you have switch off the db initialization in your application. Put this in your global.asax/Startup.cs

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

Database.SetInitializer<YourDbContext>(null);

It tells EF to stop comparing your actual DB structure against your DbContext. It also means that if someone changes your EF mapped tables, you have no chance of getting notified about that.

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

#4


0  

It looks like you used a tool like Entity Framework Power Tools to generate the entity classes and mappings. This would have generated a class for each table in the database, a huge context, mappings for all these classes and all possible associations. This is way too much.

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

First remove all classes and mappings that you don't need. Then remove all associations to removed classes in the few classes you have left, not the primitive foreign key fields. Also remove all DbSets from the context except the few you need.

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

This slimmed-down class model will be consistent in itself. It won't have associations to all entities in the database, but it will be possible to filter by foreign key values that refer to entities outside the context.

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

If you generated/created the code in any other way this is still the crux: only use navigation properties to other classes in the class model. For other references use primitive foreign key properties.

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