[英]Linq throws exception on .Substring()
我有一种情况,我需要让我的LINQ to Entities查询根据字符串的长度返回一个子字符串。 这是查询:
var query = (
from f in Context.Files
orderby f.DateAdded descending
select new
{
Concerns = f.Concerns.Name,
Sender = f.Sender.Name,
CategoryCount = f.Categories.Count(),
DateAdded = f.DateAdded,
Comment = (f.Comment == null || f.Comment.Length < 5)
? f.Comment : f.Comment
}).Take(10);
因此,我正在做的是获取文件类型最后10个添加的实体,然后从中选择一组属性以显示在列表视图中。 一些是纯字符串(关注,发件人)。 CategoryCount返回与File对象关联的类别数。
但是,如果长度大于给定的长度,我希望将其截断。 在上面的代码中,一切正常。 现在,当我替换此行时:
Comment = (f.Comment == null || f.Comment.Length < 5)
? f.Comment : f.Comment
用这行:
Comment = (f.Comment == null || f.Comment.Length < 5)
? f.Comment : f.Comment.SubString(0,5)
应用程序抛出XamlParseException(???)
匹配指定绑定约束的类型为'DocumentManager.Views.ListEntriesView'的构造方法的调用引发了异常
我真的不知道为什么会那样做。 LINQ不支持SubString方法吗?
希望有人可以在这里帮助我。 在那之前,我将保持现状。
编辑2(以某种方式,我的第一次编辑丢失了。所以我要重做):根据我得到的注释,我将代码更改为此,现在可以使用:
var query = App.Context.Files.OrderByDescending(File => File.DateAdded).Take(10).AsEnumerable()
.Select(File => new
{
Concerns = File.Concerns.Name,
Sender = File.Sender.Name,
CategoryCount = File.Categories.Count(),
DateAdded = File.DateAdded,
Comment = (File.Comment == null || File.Comment.Length < 100) ? File.Comment : File.Comment.Substring(0, 100) + "..."
});
我忘了提到我正在使用SQLite。 因此,也许在SQLite EF提供程序中未实现子字符串。
实际上这不是LINQ的错。 您的模型绑定到IQueryable,即数据库直接支持的例程(其他所有抛出异常)。 您应该在某个时候使用AsEnumerable方法来执行其他所有操作。
在Bill Wagner在这里解释IQueryable和IEnumerable之间的区别时,请阅读更多内容:
我不确定,但是我怀疑Linq-to-Entities不支持子字符串。 我将把Take(10)移到select语句之前,然后在Take(10)之后调用AsEnumerable(),然后在那之后使用select语句。 这将导致您从数据库中拉回文件的集合,然后将在内存中进行投影。
这似乎是SQLite解析器中的错误,因为
子字符串可以正常工作,以使用LINQ to Entities查询SQL Server数据库
如果查看生成的SQL日志,它将作为Substring SQL函数生成
在SQLite中,正确的函数是substr,而不是substring
因此,在生成查询的方式中存在一个错误。
这是修复此错误的一种方法。
在您的数据库模型中,在EntityContainer之前添加此代码
<Function Name="substr" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" ReturnType="nvarchar">
<Parameter Name="text" Type="nvarchar" Mode="In" />
<Parameter Name="startPos" Type="int" Mode="In" />
</Function>
在您的上下文类中(在它旁边创建一个局部类),添加以下代码
[DbFunction("MyModel.Store", "substr")]
public string SubStr(string text, int startPos) {
return text.Substring(startPos);
}
在您的代码中,以这种方式调用Substring
context.SubStr(text, startpos)
现在它将正确映射到SUBSTR函数,而不是SUBSTRING! 就像映射用户定义函数一样,不同之处在于我们映射到现有的标准函数。
希望这可以帮助!
正确-LINQ不支持子字符串,但是不幸的是,当您尝试此类操作时,从异常中并非总是很清楚。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.