2017-06-16 115 views
3

我正在使用ASP.NET MVC和SQL Server 2012製作一個Intranet網站。我正在使用洋蔥體系結構進行存儲庫和架構設計。我的問題是,我所在的公司已經有幾個服務器數據庫,其中表格之間沒有任何關係。相反,有表格來映射這些關係。例如,一個表User和一個Document Document有一個表User_joint_Document來創建一個關係,包含兩個ID(IDDocument和IDUser)。現在,當我寫我的通用倉庫:實體框架和存儲庫模式概念上的困難

class Repository<T> : IRepository<T> where T : class 

問題是通用類型T是沒有意義的,並使用EF查詢,這是正常的,我不能影響我的模型值,什麼將是巨大的。將有一個父類BaseEntity來爲每個表定義的ID,那麼我可以這樣寫:

class Repository<T> : IRepository<T> where T : BaseEntity 

和我所有的錶款會從BaseEntity繼承。但這也意味着以關係方式重寫整個數據庫並手動映射每個數據庫POCO(如果我錯了,請糾正我),並且我沒有技能來做到這一點(不同服務器數據庫中有超過300個表而且我沒有適當的知識和經驗來做這種手術)。

有沒有辦法讓我的原始數據庫結構,仍然寫一個通用儲存庫?如何去做這件事?

編輯澄清我的問題,因爲@saeb部分回答我的問題。我可以有一個通用的回購沒有我的數據庫POCO父級?或者我需要它以便只有一個存儲庫來統治它們?例如:

class Repository<T>:IRepository<T> where T : class 
{ 
    private readonly ApplicationContext context; 
    private DbSet<T> entities; 
    public Repository(PrincipalServerContext context) 
    { 
     this.context = context; 
     entities = context.Set<T>(); 
    } 
    public T Get(long id) 
    { 
    return entities.SingleOrDefault(s => s.IDUser == id); 
    //This does not work, IDUser isn't recognized 

    } 

感謝您的幫助!

+0

你給Users'的'和'Documents'在數據庫中正確的實例的更清潔的方式。一個用戶可以有許多文檔,所以你需要一個'User_joint_Document'聯結表。這正是應該如何構建關係數據庫的結構。 – melkisadek

+1

但是,如果您使用的是洋蔥體系結構,則會自動爲您創建存儲庫,您只需在DataOnion中註冊它們即可。 –

+0

@melkisadek Bah!這就是我在DB上工作的糟糕之處。我會認爲你會在兩張桌子之間有類似1-1的關係或者類似的東西?也許那個rel'ship是一個真正的桌子?真的不是我強大的一面。如果我用ID創建父類,那麼關係表會變成什麼?由於它有IDDocument和IDUser,但現在我只能從父類 –

回答

3

...在該表具有相互之間沒有關係的幾個服務器的DB ...

但他們有關係,一個Many-to-Many關係,這是通過該定義第三映射表(無論這是一個正確定義關係是另一個話題)

...問題是通用類型T是沒有意義的,我不能影響我的模型中使用EF查詢的值...

爲什麼不是這樣,爲什麼你不能?考慮你的表的例子,你有兩個實體,UserDocument,他們會是這樣的:

public class User 
{ 
    public int IDUser { get; set; } 

    public virtual ICollection<Document> Documents { get; set; } 

    ... 
} 

public class Document 
{ 
    public int IDDocument { get; set; } 

    public virtual ICollection<User> Users { get; set; } 

    ... 
} 

而且你可以使用流利的API您的上下文的OnModelCreating建立通過第三表的關係:

public class YourContext: DbContext 
{ 
    ... 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<User>() 
      .HasMany<Document>(u => u.Documents) 
      .WithMany(d => d.Users) 
      .Map(userJointDocument => 
       { 
        userJointDocument.MapLeftKey("IDUser"); 
        userJointDocument.MapRightKey("IDDocument"); 
        userJointDocument.ToTable("User_joint_Document"); 
       }); 
    } 

    ... 
} 

然後,如果它們之間有直接的關係,你可以查詢在你的倉庫User S和Document S作爲你會的。 Heremoresources瞭解更多關於這個,如果你喜歡。

+0

感謝您的確切答案和良好的文檔。我已經這樣做了,但是我的回購仍然存在問題,我無法識別這些ID。我編輯了我的問題,以顯示我的回購看起來像 –

+0

不能標記你很奇怪 –

1

至於我能看到你的問題,現在有實現這一目標沒有把至少一個基類或您的實體的接口/波蘇斯

你可以玩弄的表達式實現一個通用的存儲庫的方式

public interface IEntity<T> where T : class 
{ 
    Expression<Func<T, bool>> GetByIdPredicate(long id); 
}   

public partial class User : IEntity<User> 
{ 
    public int UserID { get; set; } 

    public Expression<Func<User, bool>> GetByIdPredicate(long id) 
    { 
     return (User entity) => entity.UserID == id; 
    } 
} 

class Repository<T>:IRepository<T> where T : class, IEntity, new() 
{ 
    private readonly ApplicationContext context; 
    private DbSet<T> entities; 
    T dummyEntity; 

    public Repository(PrincipalServerContext context) 
    { 
     this.context = context; 
     entities = context.Set<T>(); 
     dummyEntity = new T(); 
    } 
    public T Get(long id) 
    { 
    return entities.SingleOrDefault(dummyEntity.GetByIdPredicate(id)); 
    } 

有可能也擺脫了dummyEntity

+0

哦,這是一個非常有趣的事情。我實際上重新形成了我的問題,並在這裏有另一個答案,如果你有興趣,它都使用Expression方法打包在一個方法中:https://stackoverflow.com/questions/44591796/does-a-generic-repository-需要-A-基實體類待施加-到處/ 44592318#44592318 –