2016-07-30 89 views
0

如果有一個名爲UserInfo實體,UserId是主鍵,我定義的實體如下如何在EF更新一些領域

UserInfo userInfonew = new UserInfo() 
{ 
    UserId=userInfo.UserId, 
    Email = userInfo.Email, 
    FirstName = userInfo.FirstName, 
    LastName = userInfo.LastName, 
    LastUpdateBy = GetCurrentUserGuid(), 
    LastUpdate = DateTime.Now 
}; 

如果我們要更新所有的實體領域,我們有方法如下

db.Entry(userInfonew).State = EntityState.Modified; 

db.SaveChanges(); 

如果我們要更新一些領域,例如,我們只是想更新電子郵件字段:

db.UserInfoes.Attach(userInfonew); 

db.Entry(userInfonew).Property(x => x.Email).IsModified = true; 
db.SaveChanges(); 

但是如果在這個實體中有20個字段,如果我們想更新18個字段,那麼剩下的兩個字段不需要更新,我們必須寫入18次關於db.Entry(userInfonew).Property(x => x.field).IsModified = true,有沒有什麼辦法呢?我不想多寫這麼多次。

+1

爲什麼不按照預期使用EF更改跟蹤?查詢用戶,更新您需要的任何屬性,調用'SaveChanges'。 EF將完成其餘的工作。 –

+0

如果您無法使用更改跟蹤,那麼如果您仍具有條目的原始值,則實際上也可以將整個條目的實體狀態設置爲「修改」。如果您沒有原始數據並想要控制生成的查詢以實際更新特定字段,則必須將每個屬性設置爲已修改。 – DevilSuichiro

回答

1

如果您沒有從源代碼獲取原始數據,並且如果您不想更新的屬性已知,則可以使用反射來實現您想要的功能。你所要做的就是創建一個擴展方法(也可以是普通的方法,如果你喜歡的話)而改變性質的狀態如下:

public static void SetPropertiesToModeified<TEntity>(
    this MyContext context, 
    TEntity entity, 
    List<string> propertiesNotToUpdate) 
{ 
    // Get properties to update. Get all properties and 
    // exclude the ones you do not want to update. 
    List<string> propertiesToUpdate = typeof(TEntity) 
     .GetProperties()     
     .Select(m => m.Name)   
     .Except(propertiesNotToUpdate) // exculde propeties not update 
     .ToList(); 

    DbEntityEntry<TEntity> entry = context.Entry(entity); 
    propertiesToUpdate.ForEach(
     p => entry.Property(p).IsModified = true); 
} 

然後,你可以用它喜歡:

using(MyDbContext context = new MyDbContext()) 
{ 
    UserInfo userInfo = .....; 
    context.UserInfoes.Attach(userInfo); 
    List<string> propertiesNotToUpdate = new List<string> 
    { 
     "UserId", 
     "RegistrationDate" 
    }; 
    context.SetPropertiesToModeified(userInfo, propertiesNotToUpdate); 
    context.SaveChanges(); 
}