2016-01-22 22 views
0

我不確定如何標題的標題,所以我也很感激該部分的任何想法,並會相應地更新。使用EF將LINQ查詢的結果分配給另一個對象

使用C#,標準控制檯程序。

我有一個數據庫對象與一些領域,他們中的任何或所有可能會被改變。我有另一個包含新數據的字段。 我可以一個接一個地分配他們,它的工作,但如果我只是做整個事情,它不起作用。

可能更清晰一些代碼。 首先工作的代碼: 我擁有所有需要在newStop中更新的數據。

我出門從數據庫獲取數據並將其存儲在findStop2中。 然後,我可以逐個瀏覽所有字段(此處僅顯示一個字段),並將值從newStop分配到findStop2。 當我做db.SaveChanges一切正常。

var findStop2 = (from s in db.stop_details 
     where s.customer_id == customer_id && s.stop_id == newStop.stop_id 
     select s) 
    .First(); 

//if it did not error out it found it 
findStop2.ship_date = newStop.ship_date; 

但是有很多領域。爲什麼我不能只使用:

findStop2 = newStop; 

當我做到這一點,做一個SaveChanges沒有拋出錯誤,但數據庫還沒有更新。

解決方案 - 最終改變了代碼工作:

var findStop2 = (from s in db.stop_details where 
       s.customer_id == customer_id && s.stop_id == newStop.stop_id 
           select s).First(); 
       //if it did not error out it found it 
       newStop.id = findStop2.id; 
       db.Entry(findStop2).CurrentValues.SetValues(newStop); 
+0

看看這個鏈接。這是你正在尋找的。 http://stackoverflow.com/questions/13314666/using-automapper-to-update-an-existing-entity-poco –

+0

編輯問題時,請不要單行代碼,以免滾動頁面。 –

+0

@布賴恩 - 通讀鏈接兩次,嘗試了幾件事,但沒有取得任何進展。該鏈接指的是ASP.net MVC - 我正在使用標準的C#控制檯程序,是不同的? –

回答

1

如果所有的值都是標量,你可以使用(在EF6):

db.Entry(findStop2).CurrentValues.SetValues(newStop); 

這將正確地跟蹤變化,一切

0

如果我明白你的問題的權利,你需要轉換一個對象到另一個。要做到這一點,你可以寫:

var myObject = db.stop_details 
    .Where(sd => sd.customer_id == customer_id && sd.stop_id == newStop.stop_id) 
    .Select(entity => new MyObject 
    { 
     // Your properties here 
    }) 
    .First(); 

另外,如果你執行這類操作的大量時間(我猜你這樣做),你可以使用一些映射庫,例如AutoMapper。如果您正在使用映射所有你需要的是寫的如何具體類型的對象映射到另一個,反之亦然所有可能的配置。將在所有的地方,你只需要調用類似

var myObject = Mapper.Map<OutObjectType>(inputObject)

而且它。映射器將返回到你新創建的對象設置了各個領域。

P.S.如果你決定使用Automapper它的作品非常好,繼承,接口和其他的東西,這可能會非常棘手配置

+0

我不認爲'newStop'會是一個不同的類型。 Automapper可以在同一類型的兩個實體之間工作(如果你已經定義了一張地圖),但是這是一個依賴,在這種情況下沒有意義,IMO – Jcl

0

爲什麼你不能只分配在內存中的對象,以一個從實體框架檢索,然後將其保存到數據庫中的原因是,你失去了隱藏狀態EF增加了所有的它創建的對象。所以,你的findStop2 = newStop;後,findStop2不再受你的數據庫上下文跟蹤。

您可以做的是在保存您的更改之前在您的對象directly上設置state

context.Entry(newStop).State = EntityState.Modified; 

要小心,當你做到這一點,因爲它會覆蓋您newStop對象一切在數據庫中的屬性。 (您必須設置ID,否則將添加另一條記錄的例子)。

編輯

由於JCL在漫畫中提到的,你需要做findStop2東西,因爲它是也被追蹤並因此將在數據庫中創建單獨的記錄。如果根本不需要任何屬性,則不需要從數據庫中檢索它。

,您可以調用一個context.Stops.Remove(findStop2),或做一些類似上述的東西:

context.Entry(findStop2).State = EntityState.Detached; 
+0

如果你需要從數據庫中移除firstStop,設置相同的「Id」。 – Jcl

+0

更新了幾個選項。謝謝,@Jcl – krillgar

+0

即使你有更新......我認爲'findStop2'是一個已經在數據庫中的記錄。如果您使用具有相同「Id」的新添加記錄(即使它與上下文分離)來提交數據庫,數據庫將會投訴。你可能需要事先將它完全刪除(如果有外鍵,這是有風險的),或者只是更新它的值,就像我在我的回答中所做的那樣,這似乎是OP想要的(你的'Remove'會做,但不是分離...並且您可能還想檢查外鍵上的級聯刪除等) – Jcl

相關問題