這可能不會增加很多,但萬一任何人都像我一樣瘋狂,這裏是完整的代碼,如果您需要使用DatePart/DateName爲Dr. Zim的答案構建表達式樹,還包括時間部分。顯然,爲了其他目的,您可以更改Product-> YourInitialType,ProductVM-> YourResultType和modified-> YourProperty。
編輯(1/23/08):由此生成的SQL在6.0.2和6.1.3之間更改。最初,如果值爲null,則生成的SQL將創建一個空結果。在這種情況下,我認爲這是可取的,但我可以看到爲什麼在其他情況下它不會被期望(null +「一個字符串值」= null),並且可能導致輸出不等於您希望的值。我將詳細介紹列輸出如何在下面進行更改,但蹭它是現在這將輸出空值「//::」。我只是在我的調用代碼中處理這個輸出作爲特例,並手動將其更改爲null,但其他人可能想要解決添加更強大的結果以確保空值輸出爲空。還值得注意的是,新版本中的SQL語句非常長。
public class UserProductVM {
...
private DateTime _modified;
public DateTime SetModified { set { _dateEvent = value; } }
public string Modified { get { return _modified.ToString("dd MMM yyyy @ HH:mm:ss"); } }
...
}
然後你將值賦給SetModified之,改變你這樣的代碼:
ParameterExpression paramExp = Expression.Parameter(typeof(Product));
string propertyName = "modified";
Expression propertyOrField = Expression.PropertyOrField(paramExp, propertyName);
MethodInfo datePartMethod = typeof(System.Data.Entity.SqlServer.SqlFunctions).GetMethods().Where(x => x.Name == "DatePart" && x.GetParameters().Length == 2 && x.GetParameters()[1].ParameterType == typeof(DateTime?)).First();
MethodInfo dateNameMethod = typeof(System.Data.Entity.SqlServer.SqlFunctions).GetMethods().Where(x => x.Name == "DateName" && x.GetParameters().Length == 2 && x.GetParameters()[1].ParameterType == typeof(DateTime?)).First();
MethodInfo stringConvertMethod = typeof(System.Data.Entity.SqlServer.SqlFunctions).GetMethods().Where(x => x.Name == "StringConvert" && x.GetParameters().Length == 1 && x.GetParameters()[0].ParameterType == typeof(decimal?)).First();
MethodInfo stringConcatMethod = typeof(string).GetMethods().Where(x => x.Name == "Concat" && x.GetParameters().Length == 2 && x.GetParameters()[0].ParameterType == typeof(string) && x.GetParameters()[1].ParameterType == typeof(string)).First();
MethodInfo stringTrimMethod = typeof(string).GetMethods().Where(x => x.Name == "Trim" && x.GetParameters().Length == 0).First();
Type projectedType = typeof(ProductVM);
NewExpression newHolder = Expression.New(projectedType);
MemberInfo member = anonType.GetMember("modified")[0];
var monthPartExpression = Expression.Call(null, datePartMethod, Expression.Constant("mm", typeof(string)), propertyOrField);
var convertedMonthPartExpression = Expression.Call(null, stringConvertMethod, Expression.Convert(monthPartExpression, typeof(decimal?)));
var convertedDayPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("dd", typeof(string)), propertyOrField);
var convertedYearPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("yyyy", typeof(string)), propertyOrField);
var convertedHourPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("hh", typeof(string)), propertyOrField);
var convertedMinutePartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("n", typeof(string)), propertyOrField);
var convertedSecondPartExpression = Expression.Call(null, dateNameMethod, Expression.Constant("ss", typeof(string)), propertyOrField);
var allAddedExpression = Expression.Call(null, stringConcatMethod,
convertedMonthPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant("/", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedDayPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant("/", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedYearPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant(" ", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedHourPartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant(":", typeof(string)),
Expression.Call(null, stringConcatMethod,
convertedMinutePartExpression,
Expression.Call(null, stringConcatMethod,
Expression.Constant(":", typeof(string)),
convertedSecondPartExpression
))))))))));
var trimmedExpression = Expression.Call(allAddedExpression, stringTrimMethod, new Expression[] { });
var month = Expression.Bind(member, trimmedExpression);
MemberInitExpression memberInitExpression =
Expression.MemberInit(
newHolder,
new MemberBinding[] { month });
var lambda = Expression.Lambda<Func<Product, ProductVM>>(memberInitExpression, paramExp);
太棒了。我剛剛使用了我的POCO,然後在最後一分鐘使用了.AsEnumerable()。選擇(p ...並且它運行得非常好。 – 2011-03-21 02:18:16
「關於此主題的冗長文章」鏈接似乎已被打破。:-( – 2015-05-22 18:25:42
@BrokednGlass好的答案。謝謝 – User 2015-06-08 09:59:00