【问题标题】:LINQ dynamic caseLINQ 动态案例
【发布时间】:2013-04-01 10:30:42
【问题描述】:

我有这个方法:

private string GetLanguage(String currentLanguage, dynamic entity)
{
    return (currentLanguage == "de" ? entity.language.German :
     currentLanguage == "fr" ? entity.language.French :
     currentLanguage == "en" ? entity.language.English :
     entity.language.English);
}

我需要它来返回一个执行类似 SQL 语句的 LINQ 表达式:

select (case when [french] is null then [english] else [french] end) as language 
from 

我怎样才能做到这一点?

Tks

编辑:

更具体一点:

我有这样的事情:

myId = 1;

from objects in context.Objects
                           where objects.Id== myId
select new
                           {
                               MyObject = new Models.MyObjects()
                               {
                                   Id = objects.ScrId,
                                   Title = LanguageFactory.GetLabelLanguage(objects.Labels)
                               }
                           }).FirstOrDefault();

并且 MyObject.Title 必须使用某种语言(英语、法语、荷兰语等)。 在 SQL 中,我通过执行以下操作解决了这个问题:

select id, (case when [french] is null then [english] else [french] end) as language 
from table

我怎样才能做一个 LINQ 表达式,它可以被翻译成类似于上面的 SQL 查询的东西?

【问题讨论】:

  • 您希望 GetLanguage 方法返回一个 linq 表达式?
  • 请问如果您知道 currentLanguage 为什么要尝试生成这样的 sql。
  • 是的,将在主查询中使用,具有以下内容:选择 id、名称、(当 [french] 为 null 时的情况,然后 [english] else [french] end)作为表中的语言
  • Davut,因为带有 currentLanguage 的列可能有空值,我需要查询“回退”到默认列,英语
  • 为什么不在代码中查询不同的列并处理回退?您的备用方案确实不适合从 LINQ 转换为 SQL...

标签: c# .net sql linq linq-to-sql


【解决方案1】:

您将无法在 Linq-to-SQL 中调用任意函数。但是你可以使用Expression,像这样:

private Expression<Func<DbObject, MyObject>> GetObjectWithLanguage =
    e => new MyObject
    {
        Id = e.ScrId,
        Title = e.currentLanguage == "de" ? e.Labels.language.German :
                e.currentLanguage == "fr" ? e.Labels.language.French :
                e.currentLanguage == "en" ? e.Labels.language.English :
                e.Labels.language.English
    };

...
var results = context.Objects.Where(e => e.Id == myId).Select(GetObjectWithLanguage);

这将使用实体本身的currentLanguage 属性来确定要返回的内容。但是,如果您想将 currentLanguage 作为 c# 代码中的参数传递,请尝试以下操作:

private Expression<Func<DbObject, MyObject>> GetObjectWithLanguage(string currentLanguage)
{
    if (currentLanguage == "de")
    {
        return e => new MyObject
        {
            Id = e.ScrId,
            Title = e.Labels.language.German
        }
    }
    else if (currentLanguage == "fr")
    {
        return e => new MyObject
        {
            Id = e.ScrId,
            Title = e.Labels.language.French
        }
    }
    ...
}

var results = context.Objects.Where(e => e.Id == myId).Select(GetObjectsWithLanguage("de"));

如果你想创建一个通用的方法,我建议你使用泛型而不是dynamic参数,例如,假设你有一个这样的接口:

public interface ILanguageAware
{
    string CurrentLanguage { get; }
    string English { get; }
    string French { get; }
    string German { get; }
}

public class ObjectWithLanguage<T> where T : ILanguageAware
{
    public T OriginalObject { get; set; }
    string LanguageText { get; set; }
}

public Expression<Func<T, ObjectWithLanguage<T>>> GetObjectWithLanguage<T>() where T : ILanguageAware
{
    return x => new ObjectWithLanguage<T>
           {
               OriginalObject = x,
               LanguageText = x.CurrentLanguage == "de" ? x.German :
                              x.CurrentLanguage == "fr" ? x.French :
                              ...
           }
}

// extension method for convenience
public static IQueryable<ObjectWithLanguage<T>> SelectWithLanguage<T>(this IQueryable<T> queryable)
{
    return queryable.Select(GetObjectWithLanguage<T>());
}

var results = context.Objectss.Where(e => e.Id == myId).SelectWithLanguage();

【讨论】:

  • 首先,tks。其次,我的目标是拥有一个接收动态参数的通用公共方法,因为我有很多具有相同语言列的模型表。我当前的方法返回一个字符串,我希望它返回一个 LINQ 表达式。公共字符串GetLanguage(字符串currentLanguage,动态实体){返回(currentLanguage ==“de”?entity.language.German:currentLanguage ==“fr”?entity.language.French:currentLanguage ==“en”?entity.language。英语:entity.language.English);我对如何将您的代码转换为我的目标感到困惑。
  • 目前我有以下方法: public Expression> GetObjectWithLanguage(dynamic entity) { string currentLanguage = GetContextLanguage();表达式> ret = e => currentLanguage == "de" ? entity.German : currentLanguage == "fr" ? entity.French : currentLanguage == "en" ?实体英语:实体英语;返回 ret;出现以下错误,“表达式树可能不包含动态操作”
  • 没有更多信息很难判断。您可能无法使用dynamic 参数,但通用方法可能会起作用。我已经用一些代码更新了我的答案,应该为您提供一些指导。
猜你喜欢
  • 2011-01-02
  • 2018-11-01
  • 2010-10-30
  • 2011-11-27
  • 1970-01-01
  • 1970-01-01
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多