簡體   English   中英

將相同的斷開實體的不同實例插入實體框架

[英]Inserting different instances of same Disconnected Entities into Entity Framework

在我的MVC4項目中,我嘗試使用EF5將從excel工作表填充的一些數據插入數據庫(使用12c ODAC的Oracle 10g DB)中。

故事:

首先,我從excel中讀取數據,然后將它們轉換為實體。 但是,excel數據沒有“主鍵(ID)”列(我無法控制EXCEL數據)。 因此,對於excel中的每一行,我首先在DB中搜索匹配項。 如果有匹配項,我將使用DbContext獲得匹配的實體。 在這種情況下,我實例化的類/實體具有ID屬性。

另一方面,如果數據庫中沒有匹配項,我將實例化沒有ID信息的新的實體類型類。 如果實體存在於多於一行的excel工作表中,則我的最終列表將具有多個相同實體的實例,每個實例的ID = 0。

填充數據后,我將我的實體一一添加到我的DbContext中,並調用上下文的SaveChanges()方法。 然后,當我檢查數據庫時,我看到同一類的不同實例獲得了不同的ID,但這不是我想要的。

我理解為什么會這樣,因為如果未設置PK,DbContext無法關聯類的不同實例。 所有實體的EntityState變為已添加:(

我的問題是:

“是否有一種方法可以告訴實體框架,如果“一個實體的所有屬性彼此都相等且&/未設置PK / ID”,則在插入數據庫時​​將這些實體視為相同的實體?”

簡化:

在下面的代碼中執行MyMethod()之后,我只希望在數據庫表中創建一行數據:

// I implemented IEquatable to see if it works for EF (I heard it works in NHibernate) but unfortunately not working.
public class MyEntity(): IEquatable<MyEntity>
{
    // This is an autoincrementing PK in DB
    public int ID { get; set; }
    public string Name { get; set; }

    public bool Equals(MyEntity other)
    {
        if (other == null) return false;
        if (ReferenceEquals(this, other)) return true;

        return Equals(this.ID, other.ID) && Equals(this.Name, other.Name);
    }

    public override bool Equals(object obj)
    {
        return Equals(obj as MyEntity);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var result = this.ID.GetHashCode();
            result = (result * 397) ^ (this.Name!= null ? this.Name.GetHashCode() : 0);
            return result;
        }
    }
}

public void MyMethod()
{
    DbContext db = new DbContext();

    db.MyEntity.Add(new MyEntity { Name = "Foo" }) // ID=0 initially.
    db.MyEntity.Add(new MyEntity { Name = "Foo" }) // ID=0 initially.

    // When I check, the Entities in ChangeTracker are Equal!
    // This is equal to 1.
    int distinctNewEntryCount = db.ChangeTracker.Entries<MyEntity>().Select(e => e.Entity).Distinct().Count();

    // This is equal to 2.
    // But I want it to be 1 (1 Added, 1 Unchanged or only 1 Added).
    int newEntryCount = db.ChangeTracker.Entries<MyEntity>().Count(e => e.State == System.Data.EntityState.Added);

    db.SaveChanges();
}

順便說一下,我正在使用Oracle數據庫,並且在我的EDMX文件中,將自動增量PK的“ StoreGeneratedPattern”屬性設置為“ Identity”,並通過在插入觸發器之前使用插入的觸發器(在其中調用sequence.nextval())為它們分配ID值。

DbSet.Add返回添加到DbSet的實體,也許它返回的實例與傳入的實例不同。而且,SaveChanges返回什么? 應該返回添加,更新和刪除的對象數。 它是否與您要插入或更新的對象數匹配?

“如果實體存在於多於一行的excel工作表中,那么我的最終列表將具有多個相同實體的實例,每個實例的ID =0。”

那可能也是一個問題。 您說重復/共享的行將獲得其自己的唯一實體實例,其ID為0。它們應使用相同的實例。

暫無
暫無

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

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