我正在尝试获取DateTime值,如果它不为null,则返回短时间字符串。我的查询如下所示: (TimeIn不可用,而TimeOut为NULLABLE)
var times = from t in db.TimePostings
where t.MemberID == member.MemberID
select new
{
Date = t.TimeIn.ToShortDateString(),
TimeIn = t.TimeIn.ToShortTimeString(),
TimeOut = t.TimeOut.HasValue ? t.TimeOut.Value.ToShortTimeString() : "-------"
};
gvTimePostings.DataSource = times;
gvTimePostings.DataBind();
但是当我尝试使用错误数据绑定时失败:
无法翻译表达式'表(TimePosting)。其中(t => (t.MemberID == Invoke(value(System.Func
1[System.String])))).Select(t => new <>f__AnonymousType8
4(Date = t.TimeIn.ToShortDateString(),TimeIn = t.TimeIn.ToShortTimeString(),TimeOut = IIF(t.TimeOut.HasValue,(t.TimeOut ?? 调用(值(System.Func`1 [System.DateTime的])))。ToShortTimeString(), “-------”),Hours =“”))'进入SQL并且无法将其视为本地 表达
如果我尝试使用,我也会收到类似的错误:
TimeOut = t.TimeOut.HasValue ? Convert.ToDateTime(t.TimeOut).ToShortTimeString() : "-------"
但是,如果我将TimeOut属性更改为:
TimeOut = t.TimeOut.HasValue ? t.TimeOut.ToString() : "-------",
它工作正常,但不会像我想要的那样格式化时间(shortTimeString)。
这是怎么回事?
答案 0 :(得分:9)
正如其他人所说,问题在于尝试将ToShortDateString
等转换为SQL。幸运的是,这很容易解决:使用SQL获取数据,然后在.NET中格式:
var timesFromDb = from t in db.TimePostings
where t.MemberID == member.MemberID
select new { t.TimeIn, t.TimeOut };
var times = from t in timesFromDb.AsEnumerable()
select new
{
Date = t.TimeIn.ToShortDateString(),
TimeIn = t.TimeIn.ToShortTimeString(),
TimeOut = t.TimeOut.HasValue
? t.TimeOut.Value.ToShortTimeString()
: "-------"
};
此处对AsEnumerable()
的调用基本上意味着,“停止尝试使用SQL处理查询;在LINQ to Objects中完成其余工作”。
答案 1 :(得分:6)
ToShortTimeString()
在SQL中没有翻译。因此,将语句转换为单个SQL语句失败并抛出异常。
如果你将语句分成两个调用(一个用于检索数据而另一个用于创建投影),那么事情就可以了:
// must call ToList to force execution of the query before projecting
var results = from t in db.TimePostings
where t.MemberID == member.MemberID
select new { t.TimeIn, t.TimeOut };
var times = from t in results.AsEnumerable()
select new
{
Date = t.TimeIn.ToShortDateString(),
TimeIn = t.TimeIn.ToShortTimeString(),
TimeOut = t.TimeOut.HasValue ?
t.TimeOut.Value.ToShortTimeString() :
"-------"
};
答案 2 :(得分:2)
你试过了吗?
TimeOut = t.TimeOut.HasValue ? t.TimeOut.ToString("d") : "-------",
这通常会给出DateTime
的短格式。它是否有效将取决于它是否可以转换为SQL。
如果它不起作用,您必须将查询分为两部分。第一个获取数据,第二个获取数据。您必须将第一个查询转换为列表(.ToList()
)以强制SQL进行评估。
答案 3 :(得分:2)
简单来说,这个特定的linq提供商不支持它。
您的linq查询将转换为表达式树。由SQL Linq提供程序将此表达式树转换为SQL。可以理解的是,它没有能力翻译每一个.NET函数。
您的解决方案是通过调用ToArray
或ToList
显式运行SQL,然后允许LinqToObjects处理其余的SQL。
var times = from t in db.TimePostings
where t.MemberID == member.MemberID
select new {
TimeIn = t.TimeIn,
TimeOut = t.TimeOut
};
var timesFormated = times.ToArray() // Runs the query - any further processing will be run in memory by the local .NET code
.Select(t => new {
Date = t.TimeIn.ToShortDateString(),
TimeIn = t.TimeIn.ToShortTimeString(),
TimeOut = t.TimeOut.HasValue ? t.TimeOut.Value.ToShortTimeString() : "-------",
Hours = ""
}
);
答案 4 :(得分:1)
您的查询由LINQ转换为针对您的数据库触发的SQL,并且显然无法将t.TimeOut.Value.ToShortTimeString()
转换为SQL。
可能的解决方案是:
.ToList()
或.ToArray()
),将IQueryable<>
转换为IEnumerable<>
,然后为每个应用转换行取了。答案 5 :(得分:0)
我在vb.net的项目中遇到了同样的问题。 我发现的解决方案基于以下用途:
if(table.field.hasvalue, table.field.value.ToShortDateString, string.format("NULL"))
在这种情况下,如果所选字段(table.field)具有值,则将其转换为日期字符串,否则如果该字段没有值,则输出字段将填充字符串“NULL”