实体框架可扩展框架

时间:2012-02-27 13:31:16

标签: c# entity-framework entity-framework-4.1 ef-code-first

在许多项目中,我必须创建一个包含用户的表并实现基于用户的标准功能,例如身份验证,保存等。所以我决定创建一个包含这些功能的类库,例如:

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>的{​​{1}}。如果我删除了库中的MyDbContext,则DbSet<User>类将不再有效。有关如何构建可扩展框架的任何想法吗?

3 个答案:

答案 0 :(得分:2)

不要继承User,而是将User作为部分类并以此方式扩展User。这只适用于您的库只是一组源文件,而不是编译成程序集。

编辑:

另一种选择是不在框架中定义dbcontext,并使用应用程序项目中的库类来定义它。然后,您可以在框架中调用初始化函数来执行所需的映射,并从OnModelCreating调用它。

答案 1 :(得分: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...
}

答案 2 :(得分:0)

您可以随时使用合成并让MyUser包含User属性。然后,你会有一个全新的DbContext,它有一个DbSet。

这将在数据库中创建两个表,但可能是最简单的。 (免责声明:没试过这个,你可能会遇到交叉装配问题)