将Enum.GetName(..)合并到Linq查询中

本文关键字:Linq 查询 合并 Enum GetName | 更新日期: 2023-09-27 18:26:24

我有枚举:

public enum CmdType {
    [Display(Name = "abc")]
    AbcEnumIdentifier = 0,
    [Display(Name = "xyz")]
    XyzEnumIdentifier = 1,
    ...
}

我想在查询中获得每个枚举的名称,但即使使用.WithTranslations(),我也会收到以下错误:

LINQ to Entities无法识别方法"System.String"GetName(System.Type,System.Object)"方法,而此方法不能为翻译成商店表达式。

查询:

var joinedRecord =
    (
        from m in mTable
        join b in bTable on m.Id equals b.aRefId
        select new {
            aId = a.Id,
            aAttrib1 = a.Attrib1
            ...
            bCmdType = Enum.GetName(typeof(CmdType), b.CmdType)
        }
    ).WithTranslations();

如何在查询中使用Enum.GetName(...)返回生成的值?

将Enum.GetName(..)合并到Linq查询中

LINQ to entities试图将查询转换为SQL,但未能成功,因为SQL中没有等效的Enum.GetName方法。

您需要具体化查询的结果,并将枚举值转换为内存中的名称。

var joinedRecords = (
    from m in mTable
        join b in bTable on m.Id equals b.aRefId
        select new {
            aId = a.Id,
            aAttrib1 = a.Attrib1
            ...
            bCmdType = b.CmdType
        }
).AsEnumerable() //Executes the query, further you have simple CLR objects
.Select(o => new {
    aId = o.Id,
    aAttrib1 = o.Attrib1
    ...
    bCmdTypeName = Enum.GetName(typeof(CmdType), o.CmdType)
});

您正在调用无法转换为SQL的Enum.GetName(typeof(CmdType), b.CmdType),因为Enum定义不在数据库中。如果查看您的行,您会发现有问题的Enum值的名称而不是int

试试这个:

var joinedRecord =
(
    from m in mTable
    join b in bTable on m.Id equals b.aRefId
    select new {
        aId = a.Id,
        aAttrib1 = a.Attrib1
        ...
        bCmdType = b.CmdType
    }
)
.AsEnumerable() // or ToList()
.Select( // map to another type calling Enum.GetName(typeof(CmdType), b.CmdType) )
.WithTranslations();

这样做的结果是,通过调用AsEnumerable()ToList(),您不再处理IQueryable<T>的实例(这是您原始查询返回的结果,坏的一面是,一旦您这样做,所有返回的对象都将在内存中)。因此,一旦你在内存中有了对象,你就可以像使用任何其他C#对象一样使用它们,这应该允许你使用你想要的方法。

尝试强制转换为AsEnumerable(),以便可以使用LINQ to Objects。LINQ to Entities将尝试将其转换为SQL,但没有等效的:

var joinedRecord =
    (from m in mTable
    join b in bTable on m.Id equals b.aRefId)
    .AsEnumerable()
    .Select(x =>  new {
        aId = a.Id,
        aAttrib1 = a.Attrib1
        ...
        bCmdType = Enum.GetName(typeof(CmdType), b.CmdType)
    })
   .WithTranslations();

请参阅http://www.lavinski.me/ef-linq-as-emumerable/