【问题标题】:Creating Extension method to include subquery创建扩展方法以包含子查询
【发布时间】:2013-05-13 13:33:08
【问题描述】:

我在为 IQueryable 创建扩展方法时遇到问题,该方法将包含 Linq 查询中指定列的翻译。

假设我有以下查询。 我想在 CFG_Article IQueryable 上调用一个方法 IncludeTranslation,指定我想要获取翻译的列。 有人可以帮助我朝着正确的方向前进。

var translations = 
    from t in UoW.CFG_TRANSLATION.GetAll()
    select t;

var result = (
    from a in UoW.CFG_ARTICLE.GetAll()
    select new
    {
        a,
        translation = translations
            .Where(t=> t.TR_TEXT == a.AR_NAME).FirstOrDefault()
    });

到目前为止,我想到的只是下面的代码,但这不能编译。

public static IQueryable IncludeTranslation<T>(
        this IQueryable<T> query, 
        Expression<Func<t, bool>> fieldToTranslate)
{
    // this will get an IQueryable of CFG_TRANSLATION
    var translations = GetTranslations(); 

    var result = (
        from q in query
        select new
        {
            q,
            translation = translations
                .Where(t=> t.TR_TEXT == fieldToTranslate)
                .FirstOrDefault()
        });
    // even better is to return all fields from query 
    // + the TR_TRANSLATION field from the translations table

    return result;
}

【问题讨论】:

    标签: c# linq entity-framework lambda


    【解决方案1】:

    试试这个(我不得不猜测类名是 CFG_ARTICLE 和 CFG_TRANSLATION - 根据需要替换)

    public static IQueryable IncludeTranslation(
                this IQueryable<CGF_ARTICLE> query, 
                Func<CFG_ARTICLE, CFG_TRANSLATION, bool> fieldToTranslate)
    {
        var translations = GetTranslations();
    
        var result =
            from a in query
            select new
            {
                a,
                translation = translations
                    .Where(t => fieldToTranslate(a, t))
                    .FirstOrDefault()
            };
    
        return result;
    }
    

    这样叫

    var result = query.IncludeTranslation(
        (article, translation) => article.TR_TEXT == translation.AR_NAME);
    

    【讨论】:

    • 你好qujck,你能告诉我我应该如何调用这个方法吗?我的意思是我应该为 fieldToTranslate 参数填写什么。转换表中的字段应与 IQueryable 中的字段进行比较
    • 嗨qujck,谢谢你的回答。以您为例,我现在可以编译,但在运行时出现错误。 LINQ to Entities 不支持 LINQ 表达式节点类型“Invoke”。这可能是因为实体框架无法将 func 转换为 sql 语句。有什么建议吗?
    • @Salako 我想你可能不走运:-(
    【解决方案2】:

    我找到了另一种使用通用方式返回相同结果的方法。

        public static IQueryable IncludeTranslation<S>(this IQueryable<S> source, Expression<Func<S, string>> keyField)
            where S : class
        {
            IQueryable<CFG_TRANSLATION> translations = GetTranslations();
            var trans = source.GroupJoin(translations, keyField, t => t.TR_TEXT, (s, t) => new { Source = s, Translations = t });
            var result = trans.Select(t => new { 
                Source = t.Source, 
                Translation = t.Translations
                                .FirstOrDefault() 
            });
            return result;
        }
    

    也许有人可以将其用作解决方案

    可以这样调用

    var Result = QueryableTable.IncludeTranslation(t => t.FieldToTranslate);

    【讨论】:

      猜你喜欢
      • 2018-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      • 2015-08-18
      • 2021-12-31
      • 2023-04-05
      相关资源
      最近更新 更多