繁体   English   中英

LINQ查询中的自定义方法

[英]Custom Method in LINQ Query

我将自己归结为不幸的是,LINQ to EF查询中的自定义方法令人困惑。 我浏览了一下网络,尝试检测一种使自定义方法对LINQ友好的模式,并且每个消息源都说该方法必须可以translatable into a T-SQL query ,但应用程序看起来非常多样化。 因此,我将在这里发布代码,并希望慷慨的SO denizen可以告诉我我做错了什么以及为什么。

编码

    public IEnumerable<WordIndexModel> GetWordIndex(int transid)
    {
        return (from trindex in context.transIndexes
                let trueWord = IsWord(trindex)
                join trans in context.Transcripts on trindex.transLineUID equals trans.UID
                group new { trindex, trans } by new { TrueWord = trueWord, trindex.transID } into grouped
                orderby grouped.Key.word
                where grouped.Key.transID == transid
                select new WordIndexModel
                {
                    Word = TrueWord,
                    Instances = grouped.Select(test => test.trans).Distinct()
                });

    }

    public string IsWord(transIndex trindex)
    {
        Match m = Regex.Match(trindex.word, @"^[a-z]+(\w*[-]*)*",
                              RegexOptions.IgnoreCase);
        return m.Value;

    }

通过上面的代码,我访问了一个表transIndex ,该表transIndex上是从各种用户文档中transIndex的单词索引。 问题在于并非所有条目实际上都是单词。 还保存了小节,甚至下划线,例如___________,

问题

我只想保留自定义方法IsWord返回的单词(目前我还没有真正开发解析机制)。 但是正如IsWord函数所示,它将返回一个string

因此,使用let我将自定义方法引入查询并将其用作分组参数,可以将其选择到我的对象中。 执行后,我得到了无数的:

LINQ to Entities does not recognize the method 
'System.String IsWord(transIndex)' method, and this 
method cannot be translated into a store expression."

我还需要确保仅返回与IsWord条件匹配的记录。

有任何想法吗?

就是说,就如何将IsWord方法转换为SQL而言,它不理解。

坦率地说,它并没有太大作用,为什么不将其替换为

return (from trindex in context.transIndexes
                let trueWord = trindex.word
                join trans in context.Transcripts on trindex.transLineUID equals trans.UID
                group new { trindex, trans } by new { TrueWord = trueWord, trindex.transID } into grouped
                orderby grouped.Key.word
                where grouped.Key.transID == transid
                select new WordIndexModel
                {
                    Word = TrueWord,
                    Instances = grouped.Select(test => test.trans).Distinct()
                });

EF可以将哪些方法转换为SQL,我无法提供任何清单,但是它永远无法转换您已编写的简单方法。 但是它们是一些它可以理解的内置MyArray.Contains(x) ,例如MyArray.Contains(x) ,它可以将其转换为类似

...
WHERE Field IN (ArrItem1,ArrItem2,ArrItem3)

如果要编写与linq兼容的方法,则需要创建EF可以理解并转化为SQL的表达式树。

这是让事情有点动摇的地方,但是本文可能会有所帮助http://blogs.msdn.com/b/csharpfaq/archive/2009/09/14/generating-dynamic-methods-with-expression-trees- in-visual-studio-2010.aspx

如果返回的不良记录百分比不大,您可以考虑先枚举结果集,然后再进行处理/过滤?

var query = (from trindex in context.transIndexes
             ...
             select new WordIndexModel
                {
                    Word,
                    Instances = grouped.Select(test => test.trans).Distinct()
                });
var result = query.ToList().Where(word => IsTrueWord(word));

return result;

如果记录数量太多而无法枚举,请考虑在视图或存储过程中进行检查。 这将有助于提高速度并保持代码干净。

但是,当然,使用存储过程会降低可重用性和可维护性(因为没有重构工具)。

另外,请查看另一个似乎与此类似的答案: https : //stackoverflow.com/a/10485624/3481183

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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