2014-03-13 4 views
2

У меня возникает ситуация, когда мне приходится загружать данные из нескольких таблиц в один объект, то есть у меня есть отдельные таблицы для BasicProperties и несколько видов «продвинутых» свойств (мне не разрешено рефакторинг либо базы данных, либо объектной модели).Дополнительное соединение с Entity Framework

Однако, поскольку загрузка расширенных свойств является дорогостоящей и ненужной в большинстве случаев, я хочу опустить ее, если явно не указано.

То, что я в настоящее время есть что-то вроде:

from basics in ctx.Basics 
    join numerics in ctx.Numerics on basics.ID equals numerics.ItemID 
    join alphas in ctx.Alphas on basics.ID equals alphas.Itemid 
    join cplx in ctx.Complex on basics.ID equals cplx.Itemid into complex 
    select new HodgePodge 
      { 
       Basics = basics, 
       Numerics = numerics, 
       Alphas = alpha, 
       Complex = complex 
      }; 

так что мне нужно немного (легкий) способ включить/исключить загрузку таблиц базы данных в Numerics, Alphas и Complex.

В принципе, я являюсь «гостем» в этом проекте, пытаясь оптимизировать код загрузки, поэтому мне не разрешается слишком сильно менять код, а производительность наихудшего случая должна оставаться по крайней мере одинаковой.

+1

Вы должны иметь свойства навигации определены (если некоторые из этих объединений не относятся к представлениям, это не всегда возможно), которые позаботятся об этом через ленивую загрузку - вам действительно придется явно загружать связанные объекты. –

+0

Почему вы не строите свой запрос динамически в зависимости от вашего состояния? (например, включить объединение в случае advancePropertiesRequired). Или просто два запроса по одному для каждой стороны условия. –

+0

@ PatrykĆwiek, нет, никаких свойств навигации для типа ('HodgePodge'), который мне нужно загрузить (и не могу их добавить) – SWeko

ответ

2

Вы можете перемещать join логику в select заявление, и на основе вашего типа отношений (1:1, 1:*) вы используете FirstOrDefault или Where

bool loadNumerics = true; 
bool loadAlphas = true; 
bool loadComplex = true; 

var query = from basics in ctx.Basics 
      select new HodgePodge 
      { 
       Basics = basics, 
       Numerics = ctx.Numerics.FirstOrDefault(x => loadNumerics == true && basics.ID == x.ItemID), 
       Alphas = ctx.Alphas.FirstOrDefault(x => loadAlphas == true && basics.ID == x.Itemid), 
       Complex = ctx.Complex.Where(x => loadComplex == true && basics.ID == x.Itemid), 
      }; 
+0

Но ему нужно получить список Numerics, Alphas .... не просто FirstOrDefault() –

+0

И lase one «Complex» не будет работать –

+1

@WahidBitar, в своих комментариях он заявил, что тип отношений «Numerics» и «Alphas» '1: 1, поэтому я использовал' FirstOrDefault', 'Complex' - 1: *, поэтому я использовал' Where' – Aducci

1

вы можете попробовать это:

IQueryable<HodgePodge> Query = ctx.Basics.Select(u => new HodgePodge(){ Basic = u }).AsQueryable(); 

     if(ConditionNumeric) 
      Query = Query.Join(ctx.Numerics, 
       q => q.Basic.ID, 
       n => n.Itemid, 
       (q, n) => new HodgePodge(){ Basic = q.Basic, Numeric = n }) 
      .AsQueryable(); 

     if(ConditionAlpha) 
      Query = Query.Join(ctx.Alphas, 
       q => q.Basic.ID, 
       a => a.Itemid, 
       (q, a) => new HodgePodge(){ Basic = q.Basic, Alpha = a }) 
      .AsQueryable(); 

     if(ConditionComplex) 
      Query = Query.Join(ctx.Complex, 
       q => q.Basic.ID, 
       c => c.Itemid, 
       (q, c) => new HodgePodge(){ Basic = q.Basic, Complex = c }) 
      .AsQueryable(); 

     return Query.ToList(); 
+0

Tnx для ответа, это хорошо, хотя и немного словесно :) Кроме того, мне нужно будет включить все предыдущие вещи в запрос, если все условия верны. – SWeko

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