2012-08-16 28 views
0

我正在寫使用EF4.0一個DAL類,我讀過實體框架的DAL如何實現更新和刪除正確

http://www.codeproject.com/Articles/43367/ADO-NET-Entity-Framework-as-Data-Access-Layer

http://msdn.microsoft.com/en-us/magazine/cc700340.aspx

但當我測試他們的代碼時,我遇到了Update和Delete方法的一些問題。

的DAL類的所有代碼如下:

public class FriendlinkDA : IDisposable 
{ 
    private EdiBlogEntities context; 

    public FriendlinkDA() 
    { 
     context = new EdiBlogEntities(); 
    } 

    public void Dispose() 
    { 
     context.Dispose(); 
    } 

    public FriendLink GetFriendLink(Guid id) 
    { 
     return context.FriendLink.FirstOrDefault(f => f.Id == id); 
    } 

    public void Update(FriendLink model) 
    { 
     // Way 1: (throw exception) 
     //context.Attach(model); 
     //model.SetAllModified(context); 
     //context.SaveChanges(); 

     // Way 2: 
     EntityKey key; 
     object originalItem; 
     key = context.CreateEntityKey("FriendLink", model); 
     if (context.TryGetObjectByKey(key, out originalItem)) 
     { 
      context.ApplyCurrentValues(key.EntitySetName, model); 
      //context.ApplyPropertyChanges(key.EntitySetName, model); 
     } 
     context.SaveChanges(); 
    } 

    public void Delete(FriendLink model) 
    { 
     // Way 1: 
     context.Attach(model); 
     context.DeleteObject(model); 
     context.SaveChanges(); 

     // Way 2: 
     //var item = context.FriendLink.FirstOrDefault(f => f.Id == model.Id); 
     //context.DeleteObject(item); 
     //context.SaveChanges(); 
    } 
} 

擴展方法是:

public static void SetAllModified<T>(this T entity, ObjectContext context) where T : IEntityWithKey 
{ 
    var stateEntry = context.ObjectStateManager.GetObjectStateEntry(entity.EntityKey); 
    var propertyNameList = stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select 
     (pn => pn.FieldType.Name); 
    foreach (var propName in propertyNameList) 
     stateEntry.SetModifiedProperty(propName); 
} 

在應用程序中,我使用這樣的DAL:

// Delete 
using (var optFriendlink = new FriendlinkDA()) 
{ 
    var test = optFriendlink.GetFriendLink(new Guid("81F58198-D396-41DE-A240-FC306C7343E8")); 
    optFriendlink.Delete(test); 
} 

// Update 
using (var optFriendlink = new FriendlinkDA()) 
{ 
    var testLink = optFriendlink.GetFriendLink(new Guid("62FD0ACF-40C3-4BAD-B438-38BB540A6080")); 
    testLink.Title = "ABC"; 
    optFriendlink.Update(testLink); 
} 

問題1:

在Delete()中,方式1和方式2都可以工作。哪一個更好?

問題2:

在更新(),1路給我一個例外:對象不能安裝,因爲它已經在對象範圍內。對象只能在處於未更改狀態時重新附加。

關於此陳述:context.Attach(model);

但方式2很好。

爲什麼會發生這種情況?我也在Delete()中附加模型,爲什麼Delete()工作正常?我如何正確寫入更新?

回答

1

例外說明了一切:

當它是不變的狀態的對象只能重新連接。

您更改代碼段的對象// Update下,所以這就是爲什麼它不能被重新裝上。

至於哪種方法更好。通常情況下,您將從上下文中獲取對象,處理上下文,對該對象執行某些操作,然後使用新的上下文來保存該對象。在那種情況下,使用Attach比以Id爲首的對象更舒服。