2012-02-27 4 views
2

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

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 с помощью настраиваемых моделей. Проблема заключается в том, я не знаю, как расширить пользовательскую таблицу с некоторыми дополнительными полями, например:

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 больше не будет работать. Любые идеи, как сделать расширяемую структуру?

ответ

2

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

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... 
} 
+0

Спасибо, это работает отлично! – Marthijn

2

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

EDIT:

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

+1

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

+0

@PaulTyng - Это правда. –

+0

Спасибо за ваш ответ, но (к сожалению) Павел Тинг прав. – Marthijn

0

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

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

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