I finally figured out how to do this. Basically, get the generated SQL from Entity Framework, LINQ-to-SQL, or another ORM, then parse the WHERE clause. This way, I don't have to manually parse the lambda. Then create an UPDATE clause from an anonymous type. The result is as follows:
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");
This allows me to update / delete values WITHOUT pulling them out.
And the code for it looks like this ...
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\""); }
source share