Linq сопоставление между моделями - PullRequest
2 голосов
/ 23 марта 2011

У меня есть модель данных для Entity Framework, в которой некоторые объекты имеют коллекцию атрибутов, которые можно использовать для добавления дополнительной информации. Некоторые клиенты хотели бы сопоставить эти атрибуты с «реальными» свойствами их собственной доменной модели. Пример модели данных:

public class DataEntity {  
   public Guid Id { get; set; }
   public virtual ICollection<Attribute> Attributes { get; set; }
}
public class DataAttribute {
   public Guid Id { get; set; }
   public String Name { get; set; }
   public String Value { get; set; }
}
public class DataStringAttribute : DataAttribute {
   public String Value { get; set; }
}
public class DataInt32Attribute : DataAttribute {
   public Int32 Value { get; set; }
}

И пример доменной модели:

public class DomainEntity {
    public Guid Id { get; set; }
    public String Name { get; set; }
    public Int32 Age { get; set; }  
}

Я могу довольно легко сопоставлять сущности друг с другом, но я хотел бы иметь возможность отображать выражения Linq между ними так, чтобы в клиенте это было IQueryable<DomainEntity>, но это сопоставлено с IQueryable<DataEntity> - для пример:

myDomainEntities.Where(o => o.Age > 21)

может быть сопоставлен с:

myDataEntities.Where(o => o.Attributes.OfType<DataInt32Attribute>()
    .Any(o => o.Name = "Age" && o.Value > 21);

Каков наилучший способ сделать это - возможно, написать QueryProvider, который обходит дерево выражений и переводит его в тот, который использует модель данных - Linq-to-Linq-to-EntityFramework?

Спасибо.

1 Ответ

0 голосов
/ 23 марта 2011

То, что вы пытаетесь сделать, нетипично. Возможно, вам придется переопределить поставщика Linq-to-Entity и переопределить его функции генерации запросов. Вы будете самостоятельно обходить дерево выражений, а затем динамически преобразовывать это дерево выражений в новое дерево, с которым может работать Linq-to-Entity, а затем передавать это дерево исходному поставщику для генерации запросов.

Другими словами, вы захватываете Linq-to-Entity для поддержки вашего пользовательского формата. Волосатая, но если у вас все получится, напишите об этом! Буду рад узнать, как это работает!

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

...