Расширяемая структура Entity Framework - PullRequest
2 голосов
/ 27 февраля 2012

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

public class User
{
  public int? Id {get;set;}
  public string UserName {get;set;}
  public string Password {get;set;}
}

public class MyDbContext : DbContext
{
  public DbSet<User> {get;set;}
}

public class UserService
{
  public MyDbContext Context {get;set;} // will be initialized in constructor

  public User GetByUserName(string username)
  {
    return (from s in Context.Users where s.UserName.Equals(username) select s).SingleOrDefault();
  }

  // etc...
}

Теперь, когда я запускаю новый проект Mvc, я добавляю эту библиотеку и расширяю DbContext пользовательскими моделями.Проблема в том, что я не знаю, как расширить таблицу User некоторыми дополнительными полями, например:

public class MyUser : User
{
   public bool IsApproved {get;set;}
}

public class CustomDbContext : MyDbContext
{
  public DbSet<SomeOtherModel> {get;set;}

  // problem: override DbSet in MyDbContext with class MyUser?
  //public DbSet<MyUser> {get;set;}
}

В этом случае мне также нужно переопределить DbSet<User> MyDbContext.Если я удалю DbSet<User> из библиотеки, мой класс UserService больше не будет работать.Есть идеи как сделать расширяемый фреймворк?

Ответы [ 3 ]

2 голосов
/ 27 февраля 2012

Вы можете использовать дженерики (я не проверял это, просто мысль):

public abstract class UserDbContext<TUser> : DbContext where TUser : User
{
  public DbSet<TUser> Users {get;set;}
}

А потом наследовать:

public class CustomDbContext : MyDbContext<MyUser>

И тот же дженерик в UserService:

public abstract class UserService<TUser> where TUser : User
{
  public UserDbContext<TUser> Context {get;set;} // will be initialized in constructor

  public TUser GetByUserName(string username)
  {
    return (from s in Context.Users where s.UserName.Equals(username) select s).SingleOrDefault();
  }

  // etc...
}
2 голосов
/ 27 февраля 2012

Не наследуйте от User, вместо этого сделайте User частичным классом и расширьте User таким образом. Это работает только в том случае, если ваша библиотека представляет собой просто набор исходных файлов и не скомпилирована в сборку.

EDIT:

Другой вариант - просто не определять dbcontext в вашей инфраструктуре, а определять его, используя ваши библиотечные классы в проекте приложения. Затем вы можете вызвать функцию инициализации в вашей среде, чтобы выполнить необходимые преобразования, и вызвать ее из OnModelCreating.

0 голосов
/ 27 февраля 2012

Вы всегда можете использовать композицию и MyUser содержать свойство User.Тогда у вас будет совершенно новый DbContext, который будет иметь DbSet.

Это создаст две таблицы в базе данных, но, вероятно, является самым простым.(заявление об отказе: не пробовал, и вы можете столкнуться с проблемами при сборке)

...