Я наконец-то нашел способ сделать это.По сути, получите сгенерированный SQL из Entity Framework, LINQ-to-SQL или другого ORM, а затем проанализируйте предложение WHERE.Таким образом, мне не нужно разбирать лямбду вручную.Затем создайте предложение UPDATE из анонимного типа.Результат выглядит так:
Update<Task>(
new { UserID = 1, TaskCount = IncrementOf(1), SomeOtherField = DdNull } //Update
w => w.Priority != "High" && (w.Status != "Complete" || w.Status == null) //Where
);
Delete<Task>(w => w.UserID == userID && w.Status != "Complete");
Это позволяет мне обновлять / удалять значения БЕЗ извлечения их первыми.
И код для него выглядит так ...
protected void Update<T>(object values, Expression<Func<T, bool>> where) where T : class
{
Domain.ExecuteStoreCommand(
"UPDATE {0} SET {1} WHERE {2};",
GetTableString<T>(),
GetUpdateClauseString(values),
GetWhereClauseString(where)
);
}
protected string GetUpdateClauseString(object obj)
{
string update = "";
var items = obj.ToDictionary();
foreach (var item in items)
{
//Null
if (item.Value is DBNull) update += string.Format("{0} = NULL", GetFieldString(item.Key));
//Increment
else if (item.Value is IncrementExpression) update += string.Format("{0} = {0} + {1}", GetFieldString(item.Key), ((IncrementExpression)item.Value).Value.ToString());
//Decrement
else if (item.Value is DecrementExpression) update += string.Format("{0} = {0} - {1}", GetFieldString(item.Key), ((DecrementExpression)item.Value).Value.ToString());
//Set value
else update += string.Format("{0} = {1}", GetFieldString(item.Key), GetValueString(item.Value));
if (item.Key != items.Last().Key) update += ", ";
}
return update;
}
protected string GetWhereClauseString<T>(Expression<Func<T, bool>> where) where T : class
{
//Get query
var query = ((IQueryable<T>)Domain.CreateObjectSet<T>());
query = query.Where(where);
ObjectQuery queryObj = (ObjectQuery)query;
//Parse where clause
string queryStr = queryObj.ToTraceString();
string whereStr = queryStr.Remove(0, queryStr.IndexOf("WHERE") + 5);
//Replace params
foreach (ObjectParameter param in queryObj.Parameters)
{
whereStr = whereStr.Replace(":" + param.Name, GetValueString(param.Value));
}
//Replace schema name
return whereStr.Replace("\"Extent1\"", "\"Primary\"");
}