繁体   English   中英

Linq在.Substring()上引发异常

[英]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之间的区别时,请阅读更多内容:

http://msdn.microsoft.com/en-us/vcsharp/ff963710

我不确定,但是我怀疑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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM