我有一种情况需要让我的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个类型为Files的实体,然后从中选择一组属性以显示在listview中。有些是简单的字符串(Concerns,Sender)。 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 Provider中可能没有实现Substring。
答案 0 :(得分:3)
实际上并不是LINQ的错。您的模型绑定到IQueryable,即数据库直接支持的例程(其他一切都抛出异常)。您应该在某些时候使用AsEnumerable方法来完成其他任务。
阅读更多内容,比尔瓦格纳解释了IQueryable和IEnumerable之间的区别:
答案 1 :(得分:2)
我不确定,但我怀疑Linq-to-Entities不支持子字符串。我会将你的Take(10)移到你的select语句之前,然后在Take(10)之后调用AsEnumerable(),之后你的select语句。这将导致您从数据库中撤回一组文件,然后投影将在内存中完成。
答案 2 :(得分:1)
这似乎是SQLite解析器中的一个错误,因为
Substring正常工作,可以使用LINQ to Entities查询到SQL Server数据库
如果您查看生成的SQL日志,它会将其生成为子串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!它与映射用户定义函数类似,只是我们映射到现有的标准函数。
希望这有帮助!
答案 3 :(得分:0)
正确 - LINQ不支持子字符串,但是当您尝试这样的事情时,异常并不总是非常清楚。