Entity framework 4 实体框架4/Linq:如何在查询中从DateTime转换为字符串?

Entity framework 4 实体框架4/Linq:如何在查询中从DateTime转换为字符串?,entity-framework-4,linq-to-entities,tostring,Entity Framework 4,Linq To Entities,Tostring,我有以下疑问: from a in Products select new ProductVM { id = a.id, modified = a.modified.ToString() } 这给了我一个错误: LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translate

我有以下疑问:

from a in Products
select new ProductVM
    {
         id = a.id,
         modified = a.modified.ToString()
    }
这给了我一个错误:

LINQ to Entities does not recognize the method 'System.String ToString()'
method, and this method cannot be translated into a store expression.
产品表中修改的
为DateTime。
ProductVM类中修改的
是字符串

有什么想法吗?这是一个无关紧要的问题。

ToString()
在Linq to实体中不受支持-有一个函数帮助程序列表作为的一部分,但它不支持日期到字符串的转换

最简单的方法是首先在查询中投影到匿名类型,然后使用-将其转换为
IEnumerable
,然后可以使用
ToString()
,因为现在对查询表达式的其余部分使用Linq to对象(关于这个主题有一篇很长的文章)

这里有一个替代方案:

.Select( p -> SqlFunctions.StringConvert((double)
                  SqlFunctions.DatePart("m", p.modified)).Trim() + "/" +
              // SqlFunctions.DateName("mm", p.modified) + "/" + MS ERROR?
              SqlFunctions.DateName("dd", p.modified) + "/" +
              SqlFunctions.DateName("yyyy", p.modified)

显然,
DateName(“MM”,…)
拼写了月份名称,其中
DatePart(“MM”,…)
提供了一个数字值,因此
StringConvert()
,但这会在结果中留下空格,因此
.Trim()

,这可能不会增加很多,但以防万一有人像我一样疯狂,如果您需要使用DatePart/DateName(包括时间部分)为Zim博士的答案构建表达式树,下面是完整的代码。显然,出于其他目的,您可以更改Product->YourInitialType、ProductVM->YourResultType和modified->YourProperty

编辑(2008年1月23日):由此生成的SQL在6.0.2和6.1.3之间更改。最初,如果值为null,则生成的SQL将创建null结果。在本例中,我认为这是可取的,但我可以理解为什么在其他情况下不可取(null+“字符串值”=null),并可能导致输出不等于您希望的结果。我将在下面详细说明列输出是如何更改的,但问题是现在将输出“/::”作为空值。我只是在调用代码中将此输出作为特例处理,并手动将其更改回null,但其他人可能希望添加更健壮的结果,以确保null输出为null。值得注意的是,新版本中的SQL语句非常长

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);
ParameterExpression parameterxp=Expression.Parameter(产品类型));
字符串propertyName=“已修改”;
Expression propertyOrField=Expression.propertyOrField(参数xp,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(十进制?).First();
MethodInfo stringConcatMethod=typeof(string).GetMethods()。其中(x=>x.Name==“Concat”&&x.GetParameters()。长度==2&&x.GetParameters()[0]。参数类型==typeof(string)&&x.GetParameters()[1]。参数类型==typeof(string)).First();
MethodInfo stringTrimMethod=typeof(string).GetMethods()。其中(x=>x.Name==“Trim”&&x.GetParameters()。长度==0)。First();
类型projectedType=typeof(ProductVM);
NewExpression newHolder=Expression.New(projectedType);
MemberInfo member=anonType.GetMember(“已修改”)[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,datenamethod,Expression.Constant(“yyyy”,typeof(string)),propertyOrField);
var convertedHourPartExpression=Expression.Call(null,datenamethod,Expression.Constant(“hh”,typeof(string)),propertyOrField);
var convertedMinutePartExpression=Expression.Call(null,datenamethod,Expression.Constant(“n”,typeof(string)),propertyOrField);
var convertedSecondPartExpression=Expression.Call(null,dateNameMethod,Expression.Constant(“ss”,typeof(string)),propertyOrField);
var alladedexpression=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
))))))))));
变量
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);
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"); } }
    ...
}
from a in Products
select new UserProductVM
{
     ...
     SetModified = a.modified
}