2013-12-12 79 views
6

在我的項目中,我們使用的是EF代碼第一次(v.6.0.0.0)和MS SQL Server 2012的實體框架6.0代碼第一 - 按主鍵

我在過濾時在一個簡單的查詢得到複製項目已經更新到實體框架第6版。 奇怪的是,在更新後的某個時候,我開始獲取重複的項目,同時通過主鍵過濾記錄。

首先,我開始得到「序列包含多個元素」在下面的代碼

var cateringService = context.CateringServices 
          .SingleOrDefault(x => x.Id == query.CateringServiceId) 

我檢查了數據庫和參數例外 - 該Id主鍵 ,它被標記爲唯一,並且該參數是有效的。作爲Id設定爲在映射主鍵:

this.HasKey(x => x.Id); 

我已經取代了電話與FirstOrDefault和代碼運行良好。 我試着檢索所有正在使用下面的代碼mathing謂詞的項目:

var cateringServices = context.CateringServices 
           .Where(x => x.Id == query.CateringServiceId) 
           .ToList(); 

看來,我得到了「CateringService」實體的13個實例引用同一行。請看附截圖:

enter image description here enter image description here

除了我已經開始得到A relationship multiplicity constraint violation occurred: An EntityReference can have no more than one related object, but the query returned more than one related object.例外,同時通過實體引用訪問CateringService實體。我們正在使用懶惰的方法,並啓用延遲加載。

當試圖使用Include("CateringService")訪問'CateringService'時,所有的操作都很好,但我們不能只替換所有的SingleOrDefault調用,並且在此時刪除項目中的所有惰性加載用法。

請指教。

UPDATE

對不起,我是不太清楚。 數據庫中有一條記錄與條件匹配。 Id列設置爲主鍵,因此它是唯一的。

UPDATE 2

下面是基於流利映射由EF生成遷移代碼。

CreateTable(
      "dbo.CateringServices", 
      c => new 
       { 
        Id = c.Int(nullable: false, identity: true), 
        Name = c.String(nullable: false, maxLength: 200), 
        CreatedDate = c.DateTime(nullable: false), 
        CultureString = c.String(maxLength: 10), 
        AddressId = c.Int(), 
        CateringServiceGroupId = c.Int(), 
        ContactInformationId = c.Int(), 
       }) 
      .PrimaryKey(t => t.Id) 
      .ForeignKey("dbo.Addresses", t => t.AddressId, cascadeDelete: true) 
      .ForeignKey("dbo.CateringServiceGroups", t => t.CateringServiceGroupId) 
      .ForeignKey("dbo.ContactInformation", t => t.ContactInformationId, cascadeDelete: true) 
      .Index(t => t.AddressId) 
      .Index(t => t.CateringServiceGroupId) 
      .Index(t => t.ContactInformationId); 
+0

你的代碼中'query'的定義是什麼? ('x.Id == query.CateringServiceId') –

+0

它是一個非常簡單的類的實例 - 只有一個屬性'public Int32 CateringServiceId {get;組; }' – danyloid

+0

但我試過使用硬編碼值,例如'x => x.Id == 1'。或數據庫中的任何其他現有ID。仍然得到相同的結果。 – danyloid

回答

2

應該使用FirstOrDefault而不是SingleOrDefault。因爲你的屏幕短期有編號cloumn.So你需要想這個相同的值。

否則你需要檢查id是否是主鍵。和檢查組是身份是你的ID列

因爲

FirstOrDefault()

是當零個或多個結果預計將存在於輸入採集和調用返回如果有多個結果,則爲第一個項目,如果沒有,則爲Default。

的SingleOrDefault()

是當零個或一個結果輸入集合在預計爲,如果恰好一個結果是本呼叫返回一個結果,默認如果沒有結果和異常,如果超過一個結果

,並指這LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria

更新時間:

既然你逆向工程數據庫時,ID列未設置身份然而,代碼首款車型已經與DatabaseGeneratedOption.None集的生成實體上的Id屬性。

這會導致EF創建一個帶有Id集的插入語句,該集在將列更改爲IDENTITY後不再起作用。

您必須手動修復該配置,方法是將其設置爲DatabaseGeneratedOption.Identity或將其完全刪除,因爲這是整數字段的默認值。

您需要更改

this.HasKey(e => e.Id); 
    Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

更多deatisls

EF Code First 5.0.rc Migrations doesn`t update Identity property

Entity Framework 5 code-first not creating database

編輯:請刪除舊錶中的值,然後重新生成或刪除相同的主鍵行。如果問題尚未解決,您應該需要重新生成CateringServices表格值:)。

+0

對。但是如果你已經讀過這個問題的標題,你可能已經注意到,在FirstOrDefault應該被使用的情況下,情況並非如此。 但問題是,應該有一個單一的記錄。就像在數據庫中一樣。 而且無論如何,你的答案並沒有解決'A關係多重性約束違反發生'錯誤的問題。 – danyloid

+0

是的,但你的屏幕短有相同的價值爲Id cloumn.So你需要這個 –

+0

對。這就是我所問的。我已經說過,ID在數據庫中是唯一的。 – danyloid

0

您可以使用.Top(1)而不是.FirstOrDefault()或.SingleOrDefault()。

我是Linq的新手,但據我所知top()將只返回指定的行數。我不知道FirstOrDefault和SingleOrDefault。

+0

其實你應該使用FirstOrDefault,否則top(1)仍然返回一個IEnumberable。 如果存在_any_或返回null,則FirstOrDefault()將返回序列中的第一個項目 如果沒有項目,則SingleOrDefault將返回null,如果項目中有一個(且僅有一個),則返回null,如果有多個項目 – finman