2012-02-27 166 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。

這會在數據庫中創建兩個表,但可能是最簡單的。 (免責聲明:沒有嘗試過這一點,你可能會遇到交叉裝配問題)