2016-07-26 42 views
3

我想爲此函數創建一個通用方法,併發送用戶類和where子句中的參數。.net帶參數的泛型方法IQueryable <T>和表達式<Func<T, T>>

public void Update(where clause, User user) {} 

但我找不到一個正確的方法。

ctx.Users.Where(x => x.Id == 10) 
     .Update(x => new User() { Name = "Jack" }); 

的方法聲明爲:

public static int Update<T>(this IQueryable<T> query, Expression<Func<T, T>> updateFactory) where T : class; 
+0

您是否需要傳遞已經創建的用戶實例?或者你可以通過更新工廠,如'x => new User(){Name =「Jack」}'? –

+0

是的。我傳遞了之前創建的用戶實例。 – hanc

+0

'User'類是否具有除Name之外的其他屬性?如果是這樣,那麼'Update'方法也應該更新其他屬性?例如,假設有一個「Age」屬性,它是否也應該更新? 'Update'方法如何知道要更新哪些屬性? –

回答

0

如果你傳遞一個已經創建User例如,Update方法將無法知道要更新的特性(例如,它應該更新所有的人?還是那些非默認值?如果屬性有意設置爲默認值?)。

您需要傳遞一個包含成員初始化表達式的表達式,例如Expression<Func<T, T>>x => new User() { Name = "Jack" }

表達式是作爲數據的代碼。框架內部將解析表達式並查看哪些屬性打算更新。在這個例子中,它會看到只有Name屬性被打算更新。

至於表達式,你需要通過Expression<Func<User,bool>>。所以,你的方法是這樣的:

public void Update(
    Expression<Func<User,bool>> condition, 
    Expression<Func<User,User>> updateFactory) 
{ 
    ctx.Users 
     .Where(condition) 
     .Update(updateFactory); 
} 

而且你可以使用它像這樣:

Update(x => x.Id == 10, x => new User() { Name = "Jack" }); 

編輯:

如果你有辦法找到要更新的特性,你可以建立這樣的表達式:

public static void Update(
    Expression<Func<User, bool>> condition, 
    User user, 
    PropertyInfo[] propertiesToUpdate) 
{ 
    Expression<Func<User, User>> updateFactory = 
     Expression.Lambda<Func<User, User>>(
      Expression.MemberInit(
       Expression.New(typeof (User)), 
       propertiesToUpdate 
        .Select(prop => 
         Expression.Bind(
          prop.SetMethod, 
          Expression.Constant(prop.GetValue(user))))), 
      Expression.Parameter(typeof(User), "u")); 

    ctx.Users 
     .Where(condition) 
     .Update(updateFactory); 
} 

如果您只有屬性名稱,可以使用Type.GetProperty方法獲取相應的PropertyInfo

+0

如果我只想傳遞對象User並使用函數來生成表達式我該怎麼辦?我想檢查屬性是否設置爲這樣:var entry = _Context.Entry(entity); foreach(var in entry.OriginalValues.PropertyNames中的屬性) var original = entry.OriginalValues.GetValue (property); var current = entry.CurrentValues.GetValue (property); } – hanc

+0

我已更新我的答案。(原始!= null &&!original.Equals(當前)) {---屬性更改附加到表達式 } }如果您可以獲取要更新的屬性,則可以自行構建表達式。 –

相關問題