将Enum.GetName(...)合并到Linq Query中

时间:2015-12-11 18:47:55

标签: c# entity-framework linq enums

我有枚举:

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(...)返回生成的值?

3 个答案:

答案 0 :(得分:5)

LINQ to实体尝试将您的查询转换为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)
});

答案 1 :(得分:3)

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

试试这个:

Enum

这样做是通过调用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()的实例(这是您的原始查询返回的内容,一旦您执行此操作,就会发生错误所有返回的对象都将在内存中)。因此,一旦你在内存中有对象,就可以像使用任何其他C#对象一样使用它们,这些对象应该允许你使用你想要的方法。

答案 2 :(得分:2)

尝试转换为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/