LINQ动态案例

本文关键字:案例 动态 LINQ | 更新日期: 2023-09-27 18:07:04

我有这个方法:

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);
}

我需要这个来返回一个LINQ表达式做类似这样的SQL语句:

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

我怎样才能做到这一点?

谢谢编辑:

更具体地说:

我有这样的东西:

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。标题必须使用某种语言(英语、法语、荷兰语等)。在SQL中,我通过这样做来解决:

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

我如何做一个LINQ表达式,可以翻译成类似于上面的SQL查询?

LINQ动态案例

您将无法在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属性来确定返回的内容。然而,如果你想从你的c#代码传递currentLanguage作为一个参数,试试这个:

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();