2015-08-05 4 views
0

Я работаю над проектом ASP.NET MVC. Я использую EF-код-первый подход. У меня есть 3 класса, которые являются:Eager Loading with Entity Framework, LINQ

public class A 
{ 
    public int AID {get;set;} 
    public string A1 {get;set} 
    public string A2 {get;set} 

    public virtual List<B> Bs {get;set;} 
} 

public class B 
{ 
    public int BID {get;set;} 
    public string B1 {get;set} 
    public string B2 {get;set} 

    public AID {get;set} 
    public virtual A A {get;set} 

    public virtual List<C> Cs {get;set;} 
} 

public class C 
{ 
    public int CID {get;set;} 
    public string C1 {get;set} 
    public string C2 {get;set} 

    public BID {get;set} 
    public virtual B B {get;set} 
} 

Я хочу выбрать только свойства C1 класса C на основе класса B, где A1 = 4. я попытался с помощью:

var result = db.C.select(x=>x.C1).Include(x=>B).where(x=>x.A.equals(4)) 

Я запутался и не знаю, как выполнить запрос Linq. Также я не уверен, следует ли продолжать использовать нетерпеливую загрузку или вернуться к чему-то еще.

Возможно, любой гуру поможет мне?

+0

Вы хотите выбрать все свойства всех классов 'C', которые принадлежат ко всем классам' B', которые ниже относятся к классу 'A', который имеет' A1 = 4 '? – Disappointed

+0

Я не знаю, что делает ур с int 4, поэтому я просто поставил tostring на него ..... Await Db.a.where (x => x.A1.Equals (4.ToString())). Select (x => x.bs.select (y => y.cs.selectmany (z => z.c1))). tolistasync() –

ответ

2

Попробуйте это:

var result = db.C 
    .Where(c => c.B.A.A1 == 4) 
    .Select(c => c.C1) 
    .ToList() 

Вы не должны использовать жадную загрузку (Include) здесь, потому что ни один из вложенных сущностей не содержится в результате.

Eager loading Используется для обхода проблемы SELECT N + 1. Эта проблема возникает, когда вы извлекаете родительский объект и хотите итерации через своих дочерних элементов. Это приводит к N + 1 запросам, сделанным в базе данных.

Вот примеры кода для иллюстрации:

Без жадной загрузки

var carList = db.Cars.ToList(); //this will create one request to the database to retrieve all cars 

foreach(var car in carList) 
{ 
    foreach(var wheel in car.Wheels) //this line will create another request to the database to retrieve wheels for specific car 
    } 
     Console.Write("Car = {0}, Wheel = {1}", car, wheel); 
    } 
} 
//Total requests: 1 to get car list + N requests to retrieve wheels where N - total number of cars 

нетерпеливыми Загрузка

var carList = db.Cars.Include(x => x.Wheels).ToList(); //this will create one request to the database to retrieve all cars together with information about wheels 

foreach(var car in carList) 
{ 
    foreach(var wheel in car.Wheels) //this line won't create extra request to the database because this data has been already loaded using eager loading 
    } 
     Console.Write("Car = {0}, Wheel = {1}", car, wheel); 
    } 
} 
//Total requests: 1 to get car list with all wheel information 
+0

Я бы включил, что для выполнения выражения LINQ to Entities вы должны перечислить коллекцию , то есть используя 'ToList',' Count' и т. д. –

+0

Я очень благодарен Kaspars Ozols. Ваш ответ - лучшее, что я слышал. большое спасибо – Willie

0

По умолчанию EF использует отложенную загрузку, это означает, что вы выиграли» t получить, пока вы не попросите об этом. Используйте ToList() или ToArray(), чтобы EF выполнял запрос в sql и помещал эти объекты в объекты памяти. Если вам нужно, вы можете выполнить необработанный sql-запрос, например YourDbContext.SqlQuery<T>("select * from ...")

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