2013-03-06 5 views
0

Возможно ли создать вычислимое свойство в коде EF, которое может использовать другие элементы собственной таблицы?Entity Framework Code First: Вычисленное свойство, которое может иметь доступ к собственной таблице

Если нет, то что это лучший способ сделать это без использования контекстного метода (я хотел бы, чтобы свойство связывало его с интерфейсом wpf без использования преобразователей)?

Этот пример показывает, что я пытаюсь сделать (тихо легко сделать в вычисляемое поле SQL):

class MyEntity{ 

public virtual decimal Amount { get; set; } 

public virtual decimal DivideOfThisAmountOnAll 
{ 
    get 
     { 
     var sum = *******.sum(e=>e.Amount); //How am i supposed to acces to the others? 
     return this.Amount/sum; 
     } 
} 

} 

ответ

2

Вместо непосредственного изменения объектов базы данных, я бы рекомендовал сделать слой бизнес-логики для связывания , Такие инструменты, как https://github.com/AutoMapper/AutoMapper, упрощают перенос большинства ваших объектов таблицы без изменений, а затем делают такие вещи, как создание суммарных значений, сложных вычисляемых полей и других не сохраненных задач данных.

В MVC это называется Model, View, ViewModel, Controller, где ViewModel - это то, с чем вы связываетесь, и имеет все вычисленные результаты.

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

+0

Я согласен с этим в отдельном слое с вашей сущности, но я бы не предлагал вычислять агрегаты, как суммы (особенно в вашем случае, когда кажется, что вы хотите получить сумму по всей таблице). Агрегат над множеством элементов должен быть выбран как отдельный запрос, чтобы база данных эффективно обрабатывала агрегат. – AaronLS

+0

Да, это зависит от случая использования. Если я вызываю сборку подробных записей InvoiceItem и все равно потянет их всех, я бы сделал сумму в памяти (избегая просмотра). Во многих других случаях это не было бы хорошей идеей. Мое общее правило состоит в том, чтобы делать вычисления в памяти, если коллекция «завершена» в контексте, в котором я находилась, и в противном случае запускать новый запрос. – Godeke

1

Вы не можете сделать это, не обращаясь к контексту db. Вы можете придумать какую-то схему, в которой вы вводите ее в объект и т. Д., Но в основном вы будете запрашивать контекст db так же, как и с любым другим запросом.

class MyEntity{ 
    public virtual decimal Amount { get; set; } 

    public virtual decimal DivideOfThisAmountOnAll(YourDbContext db) 
    { 
     var sum = db.LinqQueryHereToAggregateAsYouPlease.Single(); 
     return this.Amount/sum; 
    } 

} 
1

Я бы предложил навигационную собственность для этого. Ответ

class MyEntity{ 

    public virtual decimal Amount { get; set; } 

    public virtual Parent Parent { get; set; } 

    public virtual decimal DivideOfThisAmountOnAll 
    { 
     get 
     { 
      var sum = Parent.MyEntities.Sum(e=> e.Amount); 
      return this.Amount/sum; 
     } 
    } 

} 

AaronLS прекрасно работает тоже, но он вводит зависимость от DbContext (если вы заботитесь о таких вещах).