簡體   English   中英

覆蓋 DLL 中的 DataModel

[英]Overriding a DataModel inside a DLL

我有一個新的 MVC 項目,我正在研究它基本上是一個我打算在其他項目中使用的 CMS,結構如下

在此處輸入圖像描述

假設我創建了一個使用我的 CMS 的 DLL 的新項目,盡管客戶需要根據其他標准將新表添加到 model,覆蓋 EcomerceModel.edmx 的最佳方法是什么,以便我可以使用新的在不觸及新創建項目的原始 Dll 的情況下添加表。

謝謝,

好吧,有一個快速的解決方案,即將你的Data項目分成幾個項目,以保持最低要求。

因此,如果我們以您的Data項目為例,它將被分成幾個 class 庫,例如:

  • Data.Models(僅包含用於抽象目的的數據模型)。
  • Data.Core(這是主要的數據項目)。
  • Data.Common(可選)
  • Data.Helpers(可選)

為此,您可能需要切換到Code First方法,以確保您可以控制遷移和模型。 (每次更新模型時,您都不需要 EF 覆蓋您的自定義設置,而且您需要將更新保存在代碼中,而不是數據庫中)。

建議將模型保存在單獨的程序集中,以便在其他項目中重復使用,而無需引用完整的數據層。

在此之后,在您的Data.Core中,您將需要引用所有其他Data.* class 庫。 然后,您可以像這樣創建DbContext

public class ECommerceDbContext : DbContext 
{
    public DbSet<Admin> Admins { get; set; }
    
    /// rest of Entities 
    

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        
        // your Entities configurations 
    }   
}

現在,您的Data層已設置好並可以在其他項目中引用。

在您想要重用當前Data.Core的其他項目中,您需要引用Data.Core (通過項目引用或 Nuget)。 然后,創建一個新的 class 繼承ECommerceDbContext來擴展它。 就像是:

public class ECommerceCMSContext : ECommerceDbContext 
{
    /// New Entities 
    

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        
        // New Entities configurations 
    }   
}

現在,使用ECommerceCMSContext將任何新表添加到當前上下文。

PS 你可以看看ASP.NET Core Identity他們正在使用類似的實現,這對你的工作很有幫助。

你的問題不是一個簡單的回答。 您要求在程序級別上進行數據映射,並且取決於您想要克服/處理多少變化將確定答案必須有多復雜。 這也可以看作是 Model Inheritance。

首先,edmx 文件對於您想要做的事情毫無用處。 它將業務 model 與數據 model 相結合,這意味着對數據或業務 model 的任何更改都會導致文件損壞。

下面的兩個選項都需要大量的工作,並且在大小方面應該被認為是一個全新的應用程序。

元數據解決方案

您可能希望查看在代碼中創建元數據/數據層並使用它來更改數據庫的外觀。

而不是通過 ecommerce.edmx 訪問 model - 通過單獨的業務/數據層訪問它。 然后,數據層可以使用動態調用或通過使用外部首選項文件來保存 sql 訪問來創建數據訪問/sql。

即在數據庫中創建外部文件、表或代碼中的資源,其中包含描述您要使用的表的元數據。 一個非常簡單的解決方案可能如下所示:

MetaTables (id, myTableName, derivedTableName)
    Order, "Order", "UserOrder"
    Customer, "Customer", "UserCustomer"

MetaAttributes (tableId, id, myAttrName, myAttrType, derivedAttrName, derivedType, etc)
    Order, Id, "Id", int, "UserId", guid
    Order, Description, "Description", string, "UserDescription", string
    Customer, Id, "Id", int, "UserId", guid

MetaRelations ()
    etc

然后使用它來動態創建您的查詢。 如果您這樣做,其他人可以使用您的代碼,並且只需要使用新映射更新您的元數據文件。 只要他們不添加新的必填列。

優勢:

  • 可以快速處理任何新的數據結構
  • 如果需要,可以動態更改數據結構
  • 版本無關

缺點:

  • 動態創建的查詢可能非常慢
  • 實現一個動態數據層需要很長時間

反射解決方案

另一種方法是將數據層存儲在單獨的程序集中並使用接口引用它。

新應用程序需要做的就是用他們的數據層替換您的數據層。

IE

public interface IDataLayer
{
    public List<IOrder> GetOrderList()
}

// MyDLL1
public class DataLayerImplementationA: IDataLayer
{
    public List<IOrder> GetOrderList()
    {
        // get data from database X, return results
    }
}

// MyDLL2
public class DataLayerImplementationB: IDataLayer
{
    public List<IOrder> GetOrderList()
    {
        // get data from database B, return results
    }
}

優勢:

  • 代碼旨在與新數據庫一起使用
  • 最快的實施
  • 編譯時間檢查!

缺點:

  • 需要使用新編譯的 DLL 覆蓋程序集
  • 多個 DLL
  • 即使是很小的更改也可能需要程序員進行大量編碼(或至少剪切和粘貼)

解決方法

如果修改真的很簡單,您可以編寫一個解析器來編輯 edmx 文件中的映射數據。 不推薦,因為這可能會導致不穩定。

另一種解決方法可能包括使用數據庫視圖隱藏更改並將數據更改處理移動到數據庫。 因此,讓舊的 edmx 文件查看視圖,使用擴展設計的新 edmx 文件查看擴展表。

變通辦法就是這樣......除了最微不足道的變化之外,它們可能會比它們所值得的更痛苦。

如果您想做一些研究,請查看使用以下術語的文章

  • Object 方向概念
  • 抽象數據層
  • Model inheritance
  • Model Controller 查看

好狩獵!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM