2012-02-27 137 views
2

在许多项目中,我不得不做出一个表包含用户和执行标准的基于用户的功能,例如认证,节能等,所以我决定把包含这些功能的一个类库,例如:实体框架可扩展的框架

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;} 
} 

在这种情况下,我还需要重写MyDbContextDbSet<User>。如果我删除库中的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 2012-02-27 14:03:57

2

不要从User继承,而应该使User成为部分类,并以此方式扩展User。这只适用于如果你的库只是一组源文件,而没有编译成汇编。

编辑:

另一种选择是根本就不在你的框架定义的DbContext,并使用你的应用程序项目库中的类定义它。然后你可以在你的框架中调用一个初始化函数来完成你需要的映射,并从OnModelCreating中调用它。

+1

如果这些类在单独的程序集中(作为可重用的库),这将不起作用 – 2012-02-27 13:42:57

+0

@PaulTyng - 确实如此。 – 2012-02-27 13:50:27

+0

感谢您的回答,但(不幸的是)Paul Tyng是正确的。 – Marthijn 2012-02-27 13:50:32

0

您可以随时使用组合并让MyUser包含用户属性。然后,您将拥有一个全新的DbContext,它将拥有一个DbSet。

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