2016-09-01 104 views
0

我有一種我認爲會相當直接的情況,但證明是困難的。BaseDbContext與共享實體

我有一個單一的數據庫,目前有兩個不同的Web應用程序使用它。每個應用程序都有專門用於該應用程序的表,同時還有幾個共享的表,例如ApplicationUser表。

我想要做的是擁有一個basecontext,它將擁有所有共享實體,並具有從basecontext派生的應用程序特定上下文。對於應用程序上下文,許多共享實體將具有派生的特定於應用程序的實體,該實體具有其他導航屬性。

我會盡力來說明的清晰:在共享庫

public class BaseContext : DbContext 
{ 
    public DbSet<ApplicationUser> ApplicationUsers { get; set; } 
} 

App1Context在應用1

public class App1Context : BaseContext 
{ 
    public new DbSet<App1User> ApplicationUsers { get; set; } 
} 

public class App1User: ApplicationUser 
{ 
    //Navigation property specific to App1 
    public virtual ICollection<SomeApp1Entity> SomeApp1Entity_Creator { get; set; } 
} 

App2Context在應用2

public class App2Context : BaseContext 
{ 
    public new DbSet<App2User> ApplicationUsers { get; set; } 
} 

public class App2User: ApplicationUser 
{ 
    //Navigation property specific to App2 
    public virtual ICollection<SomeApp2Entity> SomeApp2Entity_Creator { get; set; } 
} 

BaseCon

BaseContext文本具有ApplicationUser的dbset。

App1Context具有派生自ApplicationUser的App1User的dbset。

App2Context有一個用於App2User的dbset,它也來自ApplicationUser。

我需要特定於應用程序的用戶實體,因爲App1User可能具有不共享實體的導航屬性,並且僅適用於App1。 App2User也一樣。

我希望BaseContext的主要原因是,我可以擁有一個SharedService,它使用此上下文並擁有我的所有ApplicationUser方法用於CRUD。

我已經嘗試了幾種變化,所以如果有必要,我可以提供更多的信息,我只是不想讓這個問題太長,試圖解釋我嘗試過的一切。

我知道我希望爲BaseContext設置dbset,以便我可以擁有共享服務。在App1Context中構建模型時,我嘗試忽略ApplicationUser,因爲我認爲應該使用App1User,但這不起作用。當我這樣做時,它說沒有鍵集(因爲它忽略了具有鍵的基類,而不是在派生類中拾取它)。當我不理睬時,我會收到有關鑑別器列的錯誤。

我的第一個問題是,我是否完全用這種方法浪費了我的時間? Entity Framework 6.3甚至有可能嗎?

如果可能的話,我如何才能找到解決方案?

另外,讓我補充一點,我先使用代碼,但不擔心遷移。數據庫已經存在,並且數據庫的所有更改都在那裏進行,然後在C#代碼中相應地執行。

+0

這是可能的:'public class BaseContext:DbContext {DbSet Users {get;組; }公共類App1Context:BaseContext {}和公共類App2Context:BaseContext {}'。我們通常會從用戶實體中指定所有的導航屬性嗎?通常,其他實體將具有用戶的導航屬性以設置像UpdatedBy,CreatedBy等關係。 – Developer

+0

如果您可以格式化您的問題,將會很好 – Eldho

+0

泛型基類是否工作? 'BaseContext :DbContext where TUser:ApplicationUser'和'App1Context:BaseContext '。 –

回答

1

我不知道這是否是你在找什麼:

我一直在我的共享上下文和實體在一個單獨的庫 - SharedDbContext命名空間:

namespace SharedDataContext 
{ 
    public class BaseDbContext : DbContext 
    { 
     public BaseDbContext() : base("CFConnection") 
     { } 

     public DbSet<ApplicationUser> ApplicationUsers { get; set; } 

    } 

    public partial class ApplicationUser 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 
} 

而且創造了兩個應用程序 - WebApplication1WebApplication2

WebAp plication1 - App1Context - 擁有與外鍵關係自身的實體國家共享ApplicationUser

namespace WebApplication1 
{ 
    public class App1Context : BaseDbContext 
    { 
     public DbSet<Country> Countries { get; set; } 
    } 

    public class Country 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public int ApplicationUserId { get; set; } 
     public ApplicationUser ApplicationUser { get; set; } 
    } 
} 

WebApplication1 - App2Context - 擁有自己的實體城與外鍵關係共享ApplicationUser

namespace WebApplication2 
{ 
    public class App2Context : BaseDbContext 
    { 
     public DbSet<City> Cities { get; set; } 
    } 

    public class City 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public int ApplicationUserId { get; set; } 
     public ApplicationUser ApplicationUser { get; set; } 
    } 

} 

來自WebApplication2的樣本控制器和結果:

namespace WebApplication2.Controllers 
{ 
    public class CityController : ApiController 
    { 
     public IEnumerable<City> Get() 
     { 
      IEnumerable<City> cities; 
      using (var context = new App2Context()) 
      { 
       cities = context.Cities.Include(c => c.ApplicationUser).ToList(); 
      } 
      return cities; 
     } 
    } 
} 

結果與共享實體詳情:

enter image description here

我建議在共享實體保持上下文相關的導航,而從另一端查詢它 - 如果你需要獲取城市「用戶1」的,查詢DbSet<City> CitiesApplicationUserId == 1這本來是很容易,如果我們有ICollection<City>ApplicationUser這我不知道如何在這種情況下,實現

+0

感謝您的模擬!我其實希望做你建議不要做的事情。使用App1特定ICollections的App1User。 App1User將派生自ApplicationUser。但是,像你一樣,我不確定如何做到這一點。這看起來很簡單,但EF不喜歡它。我寧願從另一端進行查詢,而不是重複每個應用程序的所有共享代碼,所以我會繼續按照您的建議實施。非常感謝您的回覆。 – user2023116