比方說,我創建了這樣一個新的產品:如何更新由新創建脫離實體實體
Product p=new Product(){ Id= 2,Name="some name"};
我的產品變量從未被連接到數據上下文,我怎麼能把這個實體,以便我ID = 2的數據庫中的現有產品是否使用我分離的產品的名稱進行更新?
比方說,我創建了這樣一個新的產品:如何更新由新創建脫離實體實體
Product p=new Product(){ Id= 2,Name="some name"};
我的產品變量從未被連接到數據上下文,我怎麼能把這個實體,以便我ID = 2的數據庫中的現有產品是否使用我分離的產品的名稱進行更新?
我希望類似的東西會工作
Datacontext db = new Datacontext(); // replace with your DataContext
Product originalProduct =
db.Products.Single(p => p.Id == 2); // get product with Id 2
originalProduct.Name = "SomeName"; // only reset Name prop
originalProduct = p; // or you may assign p to originalProduct
db.SubmitChanges(); // submit changes to DB
有點容易的解決辦法是落實你想這樣的工作的實體ICloneable
接口。然後,您只需將Clone()調入您從數據庫中提取的「原始」實體。
例子:
class Product : ICloneable
{
public virtual int Id { get; private set; }
public virtual string Name { get; set; }
public object Clone()
{
return new Product() { Id=this.Id, Name=this.Name };
}
}
然後所有你需要做的是:
Datacontext db = new Datacontext(); // replace with your DataContext
Product originalProduct =
db.Products.Single(p => p.Id == 2); // get product with Id 2
db.originalProduct = p.Clone()
db.SubmitChanges();
編輯: 我跑進在工作中同樣的問題,迄今爲止最優雅的解決方案我找到的是建立一個擴展方法,接收新創建的實體,在你的情況Product
,並將它的屬性(標識符除外)複製到你從DataContext中提取的實體。
我通過反射覆制了所有的屬性,這樣,如果我更新了實體,那麼我的擴展方法仍然可以工作。
希望這對你也有幫助。
如果你找到一個更優雅的解決這個問題,我想聽聽:)
db.originalProduct看起來不正確...當您將p.Clone()分配給originalProduct時,它不再「附加」到上下文中,因此它不會被持久化。 – 2010-12-23 06:34:39
哦,你是對的,我沒有完全想到它......我會檢查出來並嘗試修復它。我在工作中遇到了同樣的問題,所以我需要考慮一個好的解決方案,當我這樣做時,我會解決它! :) 謝謝! – gillyb 2010-12-23 09:07:28
如果要跳過使用反射,還可以使用DataContext的MappingSource將值複製到新的克隆版本。這樣它只會複製特定於您的數據庫的屬性。 – rossisdead 2010-12-24 00:10:39
只是爲了添加到gillyb的帖子,我離開那裏的註釋。克隆你的實體一個非常簡單的方法是這樣:
Private Function CloneEntity(Of TEntity)(ByVal entity As TEntity) As TEntity
Dim dataContext As New DataContext()
Dim entityType As System.Type = GetType(TEntity)
' If the purpose of the clone is just to attach it the existing entity to a new
' DataContext, you can use IdentityMembers in place of PersistantDataMembers. Setting
' only the IdentityMembers is enough to allow for attaching the clone as an "originaL"
' entity to the DataContext.
Dim dataMembers = dataContext.Mapping.GetTable(entityType).RowType.PersistentDataMembers
Dim clone As TEntity ' Do something here to create an entity of the desired type.
Dim boxedClone As Object = clone
For Each dm In dataMembers
' Depending on how your ColumnAttribute is set, you would use StorageAccessor if
' the Storage property is set. Otherwise, you would use MemberAccessor instead.
dm.StorageAccessor.SetBoxedValue(boxedClone, dm.StorageAccessor.GetBoxedValue(entity))
Next
Return clone
End Function
然後你只需要做到這一點:
Dim dataContext As New DataContext()
dataContext.GetTable(Of Object)().Attach(entityToUpdate, CloneEntity(entityToUpdate))
dataContext.SubmitChanges()
,無疑可以工作,但可能是痛苦的,始終在屬性複製。在NHibernate中,他們有一個名爲Reattach的構造,它可以讓你指定它是數據庫中的一個現有對象,我不確定L2S是否存在。 – 2010-03-01 20:03:12
當然,但是op正在使用L2S – 2010-03-01 20:04:30