1

У меня есть классИспользование навигации для загрузки сущности 2 уровень глубокой

public class Level1 
{ 
    public int Id {get; set;} 
    public virtual List<Level2> Level2List {get; set;} 
} 

public class Level2 
{ 
    public int Id {get; set;} 
    public int Level3Id {get; set;} 
    public virtual Level3 Level3 {get; set;} 
} 

public class Level3 
{ 
    public int Id {get; set;} 
    public string Name {get; set;} 
} 

С помощью навигационных свойств я мог загрузить List<Level2> как этот

var myList = _myLevel1Repository.GetSingle(x=>x.Id == Level1Id, x=>x.Level2List); 

но как загрузить LEVEL3 и его свойства, которые связаны с уровнем 2?

PS: Lazy loading невозможно. Это Getsingle функция

public T GetSingle(Func<T, bool> where, params Expression<Func<T, object>>[] navProps) 
    { 
     T item = null; 
     using (var context = new MyDbContext()) 
      item = GetFilteredSet(context, navProps).AsNoTracking().FirstOrDefault(where); 
     return item; 
    } 

ответ

1

Ваш метод GetSingle должен быть таким образом:

public T GetSingle(Func<T, bool> where, params Expression<Func<T, object>>[] navProps) 
{ 
    T item = null; 
    using (var context = new MyDbContext()) 
    { 
     IQueryable<T> query = context.Set<T>(); 

     //Include the navigations properties as part of the query 
     if (navProps!= null) 
     { 
      query = navProps.Aggregate(query, (current, include) => current.Include(include)); 
     } 
     item = query.Where(where).FirstOrDefault(); 
    } 
    return item; 
} 

Я не знаю, что вы делаете в методе GetFilteredSet, но я думаю, вы можете реорганизовать код, который я показать выше в удобное , Ключ должен включать более одного уровня навигации. свойства в EF используют метод Include. Когда вы используете этот метод, вы загрузите навигатор. свойства как часть вашего запроса (отметьте нужную секцию загрузки в этом link). Теперь, есть два метода Include:

  • DbQuery.Include Method

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

    context.Set<Level1>.Include("Level2List.Level3"); 
    
  • DbExtensions.Include extension method

    Это метод, который я использую в моем коде выше, где вы можете указать соответствующий объекты, включающие использование выражения лямбда. ИМХО это лучший вариант, потому что он строго типизирован, и если вы меняете какую-то навигацию. имя свойства в ваших сущностях, вы также получите ошибку (ы) компиляции. В разделе link, представленном выше, вы можете увидеть все шаблоны, которые вы можете использовать для включения различных уровней навигации. свойства.

    context.Set<Level1>.Include(l1=>l1.Level2List.Select(l2=>l2.Level3)); 
    

Возвращаясь к исходной задаче, теперь вы можете использовать метод GetSingle включать более чем на один уровень так:

var entity= _myLevel1Repository.GetSingle(x=>x.Id == Level1Id, x=>x.Level2List.Select(l2=>l2.Level3)); 
+0

Ровно, первый 'Include' метод, который я упомянул это не самый лучший вариант. Вы можете ошибиться при вводе имени одного свойства, или вы также можете забыть переименовать один из них в пути, если вы измените какое-либо имя свойства на вашей модели. – octavioccl

+0

ОК, как и сказал, я изменил метод getingle. и ваша последняя строка кода работала как шарм. но не могли бы вы объяснить мне одну вещь? В этом коде 'var entity = _myLevel1Repository.GetSingle (x => x.Id == Level1Id, x => x.Level2List.Select (l2 => l2.Level3));' зачем использовать l2, как в '.select (l2 => l2.Level3) ', а не x. И я мог бы пойти еще глубже? – Cybercop

+0

Поскольку мне нужно выбрать свойство из объекта 'Level2' (который будет вашим вторым уровнем),' x' является вашим корнем.О уровнях загрузки более глубже, да, вы можете, в ссылке, которую я разделяю, связанной со вторым 'Include', вы найдете пример:' query.Include (e => e.Level1Collection.Select (l1 => l1.Level2Collection.Select (l2 => l2.Level3Reference))). ' – octavioccl

0

Как насчет использования включают?

var mylevel1s = _db.Level1(x=>x.Id == Level1Id).Include(x=> x.Level2List.Select(a=>a.Level3)); 
Смежные вопросы