2014-09-02 4 views
5

У нас есть огромная база данных с 770 таблицами и вы хотите провести тестирование производительности с помощью EF 6.1x.Entity Framework 6 DBContext с только подмножеством всех таблиц

Мы хотим запросить только 5 из этих 770 таблиц. Возможно ли создать «легкий» DBC-текст только с 5-6 сущностями/DBSets вместо использования полного контекста 770-tables?

Когда мы используем полный контекст, простой запрос с 4 соединением занимает 45 секунд. Это 44 секунды слишком долго. Мы используем код-первый (с обратной обработкой).

Проблема: Когда мы создаем такую ​​«легкую» версию полного контекста (то есть 5 таблиц только), EF жалуется, что все остальные лица, которые так или иначе связанные с этими 5 таблиц есть недостающие ключи. Мы отображаем только ключи, свойства, отношения для этих 5 таблиц, но не остальные.

Поскольку запрос, написанный в LINQ, запрашивает только 5 таблиц, EF должен просто игнорировать остальные 765 таблиц, но это не будет. Почему бы и нет? LazyLoading = true/false, похоже, не имеет никакого отношения к этому.

Примечание: Очевидно, можно создать представление в БД, которое делает то, что мы делаем в коде с запросом 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<...>(); 
    } 
} 
+1

Это, безусловно, возможно и на самом деле рекомендуется. В больших средах баз данных часто увеличение производительности имеет несколько разных контекстов для подмножеств таблиц. – DavidG

+0

Некоторый код был бы полезен для понимания вашей проблемы, но я бы предположил, что вы ищете что-то вроде http://stackoverflow.com/questions/17246069/multiple-dbcontexts-on-one-db-with-code-first-migrations? – fuchs777

+0

- простой запрос первого из exe, то есть одного запроса, вызывающего построение контекста? – tschmit007

ответ

5

что вы пытаетесь что-то вроде «ограниченного контекста», который является одним из шаблонов DDD

Таким образом, вы можете проверить эту статью Джули Лерман, Shrink EF Models with DDD Bounded Contexts

2

Если у вас есть много-к-одному отношения между классом A и классом B:

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

и определить следующую DbContext , EF автоматически включает DbSet<B> в DbContext:

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

Так что, если вы хотите, чтобы ваш свет DbContext не включает в себя соответствующие DbSet с, просто использовать Ignore метод:

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

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

спасибо! Можно ли это сделать наоборот? Call Include() при необходимости и EF игнорировать все DBS-файлы по умолчанию, а не включать их? – John

+0

@John, если вы 'Игнорируете' класс, вы не можете использовать его с' Include() '. – Masoud

+0

Я имел в виду следующее: если таблица имеет 45 ссылок на другие DBS-файлы, мне нужно вызвать Ignore() 45 раз, или есть более простой способ EXclude большого количества связанных наборов? – John

0

Похоже, что вы использовали инструмент, как Entity Framework Power Tools для создания лица классов и отображений. Это создало бы класс для каждой таблицы в базе данных, огромный контекст, сопоставления для всех этих классов и всех возможных ассоциаций. Это слишком много.

Сначала удалите все классы и сопоставления, которые вам не нужны. Затем удалите все ассоциации для удаленных классов из нескольких оставшихся классов, не примитивных полей внешнего ключа. Также удалите все DbSets из контекста, за исключением тех немногих, которые вам нужны.

Эта модель с уменьшенным классом будет самосогласованной. Он не будет иметь ассоциаций со всеми объектами в базе данных, но можно будет фильтровать значения внешнего ключа, которые относятся к объектам вне контекста.

Если вы создали или создали код каким-либо другим способом, это по-прежнему остается ключевым: используйте свойства навигации для других классов в модели класса.Для других ссылок используются свойства примитивного внешнего ключа.

+0

Я боялся, что кто-то предложит это. Я использовал инструменты электропитания, но dbcontext, который я создал из нескольких сгенерированных объектов, является лишь одним из многих dbcontext, которые нам нужны. Из того, что вы написали, я думаю, что невозможно использовать одни и те же классы сущностей в нескольких контекстах. Но тогда мне нужно будет создать один и тот же класс сущности снова и снова для каждого dbcontext? Итак, Item1.cs для dbcontext A, Item2.cs для dbcontext B и т. Д.? – John

+0

Да, в принципе, это правда. Но я думаю, вы должны попытаться создать более обширные контексты, которые охватывают разумно различные агрегаты вашей базы данных и которые обслуживают несколько областей задач. Таким образом, вы можете уменьшить количество перекрывающихся классов. [EntityFramework Reverse POCO Code First Generator] (https://efreversepoco.codeplex.com/documentation) может быть полезен здесь. –

+0

Вы можете использовать одни и те же классы сущностей в разных DbContexts, если вы создаете отдельное отображение 'EntityTypeConfiguration <...>', которое имеет 'Ignore ();' для каждого свойства навигации вы не хотите, чтобы текущий DbContext пытался для отображения. – sliderhouserules

2

Просто просто создать DbContext для таблиц. Чтобы запретить Entity Framework стонать о таблицах, не отображенных, вы отключите инициализацию db в своем приложении. Поместите это в global.asax/Startup.cs

Database.SetInitializer<YourDbContext>(null); 

Это говорит EF, чтобы перестать сравнивать фактическую структуру БД против вашего DbContext. Это также означает, что если кто-то изменит ваши сопоставленные таблицы EF, у вас нет никаких шансов получить уведомление об этом.

Смежные вопросы