2017-06-05 27 views
1

關注現在,我使用實體框架具有以下的DbContext類:分離了的DbContext

public class ItemDbContext : DbContext { 
    ... 
    public DbSet<Item1> Item1s { get; set; } 
    public DbSet<Item2> Item2s { get; set; } 
} 

有一些類需要的DbContext用兩種Item11sItem2s的依賴關係。所以我的目的是用DbSet類型爲DbContext創建一個抽象層(邏輯上獨立的DbContext_Item1和DbContext_Item2)。它也可以用於實現抽象工廠模式(也可以創建DbContext_Item1或DbContext_Item2實例)。

我的想法:

1)接口

public interface IDbContext_Item1 { 
    DbSet<Item1> Item1s { get; set; } 
} 
public interface IDbContext_Item2 { 
    DbSet<Item3> Item2s { get; set; } 
} 

所以我的抽象工廠能夠有API這樣的:

public abstract ItemFactory { 
    public abstract IDbContext_Item1 GetItem1Context; 
    public abstract IDbContext_Item2 GetItem2Context; 
} 

這將是對我很好。但是,獲得IDbContext_ItemX實例的類不會將其視爲DbContext實例(即無法調用像SaveChanges()等方法)。不幸的是,任何接口都不能像DbContext那樣從類繼承。

2)擴展接口用的DbContext

public interface IDbContext_Item1 { 
    DbSet<Item1> Item1s { get; set; } 
    void SaveChanges; 
    // etc 
} 

的方法,在我看來這是非常不優雅。

3)抽象類爲IDbContext_ItemX

但我目前的DbContext執行,ItemDbContext,不能從多個類繼承。

4)只要devide當前ItemDbContext上DbContext_Item1和DbContext_Item2 具體類

是的,這是決定。但它是唯一的方式嗎?如果我的具體工廠在發動機罩下返回ItemDbContext的實例,那將是非常好的。我能實現它嗎?

+0

這有什麼錯在同一個的DbContext有一個以上的實體?除非這兩個實體完全無關,否則沒有任何傷害。如果兩個實體與關係聯繫在一起,情況尤其如此。如果你最終在同一個DbContext中有20個實體的大熔爐,那麼做一些類似的事情,但否則,呃! – Tipx

+0

@Tipx對於很多場景都是如此,但我的想法是SoC。某些類通過抽象工廠獲取具有DbSet特定類型的DbContext實例。如果應用程序具有多種類型的實體,並且有時需要將DbContext分爲兩種,或反之亦然,那就太好了。然後,我不必重寫抽象工廠API(返回類型)和依賴關係類 – Mergasov

+0

在我看來,您正在重新創建UnitOfWork + Repository模式。確保你先知道這一點。 –

回答

0

我認爲你需要創建一些基本接口(可以稱之爲IDatabaseContext):

public interface IDatabaseContext : IDisposable 
{ 
    //base DbContext stuff like SaveChanges here 
} 

然後你嵌套接口:

IDbContext_Item1 : IDatabaseContext 
IDbContext_Item2 : IDatabaseContext 

而且你ItemDbContext實現了這兩個接口。

我同意寫所有DbContext方法IDatabaseContext接口並不優雅,但你需要做的只是一個時間

1

正如我評論,我會第一個挑戰推理希望有一個單一的實體背後一個給定的範圍內,但如果你決定去向前,我想用一個通用的接口去,甚至是一般上下文:

interface IDbContext<T> where T : class 
{ 
    IDbSet<T> Set { get; } 
} 

// Context implement generic Interface 
class DbContextItem1 : IDbContext<Item1> 
{ 
    IDbSet<Item1> Set { get; private set; } 

    override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Logic to get relevant mappings, 
    } 
} 

// Technically you could also do that. 
class DbContextItem1 : IDbContext<Item1>, IDbContext<Item2> 
{ 
    IDbSet<Item1> IDbContext<Item1>.Set { get; } 
    IDbSet<Item2> IDbContext<Item2>.Set { get; } 

    override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Logic to get relevant mappings, 
    } 
} 

// Generic context. 
class DbContextGeneric<T> : IDbContext<T> 
{ 
    IDbSet<T> Set { get; private set; } 

    override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // Logic to get relevant mappings based on T. 
    } 
}