簡體   English   中英

參考另一個上下文中的實體創建新實體

[英]Creating a new entity with reference to an entity from another context

我有2個projetcs PRJ1PRJ2 ,它們使用自己的數據庫DB1DB2 這些數據庫中的每一個都使用EF Code First Migration。

  • PRJ1用於管理產品庫存(自4年以來已存在)。
  • PRJ2用於訂單(全新項目仍在開發中)

現在我們來談談第二個項目。 在我的項目PRJ2中,我需要從其他數據庫DB1訪問數據。 所以我需要下訂單產品。

以下是我到目前為止PRJ2的內容。請注意,我定義了兩種不同的上下文。

// Context for accessing entities in DB1
public class DB1Context : DbContext
{
    static DB1Context()
    {
        Database.SetInitializer<DB1Context>(null);
    }
    public DbSet<Product> Products { get; set; }
}

// Context for accessing entities in DB2
public class DB2Context : DbContext
{
    static DB2Context()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<DB2Context, DAL.Migrations.Configuration>());
    }
    public DbSet<Anything> Anythings { get; set; }
    public DbSet<Order> Orders { get; set; }
}

什么有效 :我可以從DB1Context(Products)或DB2Context(Anythings)查詢數據。

什么不起作用 :創建我的訂單實體。

// My Orders entity
public class Orders
{
    public int Id { get; set; }
    public int ProductId { get; set; }
    public int Quantity { get; set; }

    public virtual Product Product { get; set; }
}

位於DB2Context中的此實體引用Product實體,該實體是DB1Context的一部分。

現在的問題是,只要我在我的上下文DbSet<Order>添加此實體,我DbSet<Order>看到有一個等待Product的遷移。 此遷移用於在DB2Context中創建Product。 那不是我想要的。 此實體已存在於DB1Context中。 我似乎無法創建這個從其他上下文引用Product的Order實體。

你能證實這一點嗎? 我錯過了什么嗎? 否則什么是最好的選擇?

我認為你不能使用Entity Framework做到這一點。

該問題看起來像No-SQL數據庫的問題。 當您擁有多個數據庫時,您必須控制所有數據庫的所有CRUD。 ADO無法為您執行此操作,因為您沒有數據完整性。

一種可能的解決方案是將CRUD放在業務邏輯層中......或類似的東西。

假設您有一個OrderBll來控制:

public class OrderBll
{
    private DB1Context _DB1Context = new DB1Context();
    private DB2Context _DB2Context = new DB2Context();

    public List<Orders> GetOrders()
    {
        var orders = _DB2Context.Orders.Where(???).ToList();
        var productIds = orders.Select(x => x.ProductId).Distinct().ToArray();
        var products = _DB1Context.Products.Where(x => productIds.Contains(x.Id)).ToList(); // Optimize the load of all products in orders

        // Set the product object in the order list
        foreach( var order in orders )
        {
             order.Product = products.FirstOrDefault(x=>x.Id == order.ProductId);
        }
        return orders;
    }
}

請記住,您必須在“ Ignore Orders映射“ Product屬性。

因此,您必須自己設置外鍵並執行所有約束檢查。

但是,如果其他人有更好的解決方案,我會很高興知道。

理想情況下,這是你應該瞄准的目標。

  1. 將訂單和產品放在同一個數據庫中。 然后,您就可以在訂單和產品之間創建關系。 您最終會得到一個EF上下文,這將為您提供可靠的解決方案。

如果由於某種原因您不能將訂單放在與產品相同的數據庫中,那么解決方案仍然有其自身的局限性。

  1. 例如,您可以將products表從DB1復制到DB2,每分鍾運行一次復制。 您可以編寫自己的復制組件或使用數據庫的復制功能。 如果可以在DB2中刪除產品,則復制可能會刪除DB1中的產品和訂單,或者僅標記已刪除的產品。 由你來決定。 如果PRJ2可以更新產品表,那么復制必須是雙向的。 這變得更復雜。 此解決方案的EF上下文將包含從訂單到產品,從產品到訂單的關系。

  2. 另一種解決方案是在DB1中保留一個“代理”產品表,其中包含訂單中引用的產品的ID。 在您的業務邏輯中,您決定是否需要從DB1訪問實際的產品表。 例如,在創建新訂單時,您將從DB1訪問產品,並在代理表中插入其ID(如果不存在)。 在顯示訂單的產品時,您首先要從DB1中檢索訂單的產品ID,然后從DB1中檢索它們的完整描述。 更新產品庫存時,作為創建訂單的一部分,您可以訪問DB1,可能使用跨越DB的事務! 和DB2。

暫無
暫無

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

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