2013-02-12 2 views
0

я динамически создаю мой DbContext итерации по любым лицам, которые наследуют от EntityBase и добавления их в мой контекст:Развязка Entity Framework из моих классов POCO

private void AddEntities(DbModelBuilder modelBuilder) 
    { 
     var entityMethod = typeof(DbModelBuilder).GetMethod("Entity"); 
     foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) 
     { 
      var entityTypes = assembly.GetTypes() 
       .Where(x => x.IsSubclassOf(typeof(EntityBase)) && !x.IsAbstract); 
      foreach (var type in entityTypes) 
      { 
       dynamic entityConfiguration = entityMethod.MakeGenericMethod(type).Invoke(modelBuilder, new object[] { }); 
       EntityBase entity = (EntityBase)Activator.CreateInstance(type); 

       //Add any specific mappings that this class has defined 
       entity.OnModelCreating(entityConfiguration); 
      } 
     } 
    } 

Таким образом, я могу иметь много имен, но только один общий репозиторий в моем базовом пространстве имен, который используется повсюду. Кроме того, в приложениях, использующих несколько пространств имен, базовый репозиторий уже настроен для использования всех объектов во всех загруженных пространствах имен. Моя проблема заключается в том, что я не хочу, чтобы EntityFramework.dll зависела от каждого пространства имен в компании. Поэтому я вызываю OnModelCreating и передаю EntityTypeConfiguration в класс, чтобы он мог добавлять любые сопоставления. Это прекрасно работает, и вот как я могу добавить отображение сказать модели, что моя собственность «Описание» прибывает из колонки под названием «Дескриптор»:

class Widget... { 
    public override void OnModelCreating(dynamic entity) 
    { 
     System.Linq.Expressions.Expression<Func<Widget, string>> tmp = 
      x => x.Description; 
     entity.Property(tmp).HasColumnName("Descriptor"); 
    } 

Хорошая вещь, мой класс сущности не имеет никакого отношения к EF , этот метод вызывается только один раз, когда создается контекст, и если мы откажемся от EF и перейдем к чему-то еще в будущем, мои классы не будут иметь в себе все атрибуты, специфичные для EF.

Проблема в том, что это супер уродливый. Как я могу позволить модели узнать о сопоставлениях столбцов и ключах более простым способом, чем создание этих Expressions, чтобы получить свойства для сопоставления без жестких ссылок на кодирование EF на всех моих классах poco?

+0

Вы можете реализовать шаблон родовое репо в более изящным способом, проверьте [это] (http://blog.swink.com.au/index.php/c-sharp/generic-repository-for -entity-framework-4-3-dbcontext-c-code-first /) – zsong

+0

@sza - это не упоминает о том, как добавлять сопоставления без включения ссылок EF. – powlette

ответ

1

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

public class DatabaseNameAttribute : Attribute 
{ 
    private readonly string _name; 
    public DatabaseNameAttribute(string name) 
    { 
     _name = name; 
    } 
    public string Name 
    { 
     get 
     { 
      return _name; 
     } 
    } 
} 

public class KeySequenceAttribute : Attribute 
{ 
    private readonly int _sequence; 
    public KeySequenceAttribute(int sequence) 
    { 
     _sequence = sequence; 
    } 
    public int Sequence 
    { 
     get 
     { 
      return _sequence; 
     } 
    } 
} 

[DatabaseName("BlogEntry")] 
public class Post 
{ 
    [DatabaseName("BlogId")] 
    [KeySequence(1)] 
    public int id { get; set; } 
    [DatabaseName("Description")] 
    public string text { get; set; } 
} 
+0

У нас есть существующие сопоставления из L2S, которые уже существуют и используют только пространства имен System, поэтому я думаю, что повторное использование этих функций будет работать хорошо. Моя единственная проблема заключается в том, что я не смогу легко высмеять все функциональные возможности настройки отображения EF. Но я предполагаю, что это принесет мне большую часть пути. Благодарю. – powlette