【问题标题】:Multiple Linq (Extension Method) Joins With Anonymous Types使用匿名类型的多个 Linq(扩展方法)连接
【发布时间】:2015-03-23 22:00:02
【问题描述】:

在 C# 中,我尝试进行多个扩展方法连接,其中第二个连接是第一个连接产生的匿名类型的可枚举:

List<Contact> filteredContactList = GetFullContacts()
    .Join(GetContactCompanyRoles()
        , ct => ct.IdContact
        , ctCmpRole => ctCmpRole.IdContact
        , (ct, ctCmpRole) => new { Contact = ct, ContactType = ctCmpRole.ContactType })
    .Join(GetContactRoles()
        , ctf => new { ctf.Contact.IdContact, ctf.ContactType }
        , ctRole => new { ctRole.ContactId, ctRole.ContactType }
        , (ctf, ctRole) => new { Contact = ctf.Contact, PrimaryInd = ctRole.IsPrimary})
    .Select(rec => rec.Contact)
    .ToList();

ct 和 ctf.Contact 是 Contact 类型。

但是,我在尝试编译时遇到以下错误:

方法“System.Linq.Enumerable.Join...”的类型参数无法从用法中推断出来。尝试明确指定类型参数。

有没有办法绕过这个错误,而不必从第一次加入时为匿名类型创建一个实际的类?还有其他我没有考虑的选择吗?

【问题讨论】:

  • 我建议使用查询语法编写 linq 语句,因为它更易于阅读和编写(在我看来)。
  • 我更喜欢扩展方法,我个人觉得它们更容易阅读。使用扩展方法的另一个好处是您可以将它们分解为多行代码,以便从编译器获得更清晰的错误消息。
  • 啊……那个老说法。 “方法语法与查询语法”(我是 Joins 的查询语法人 .. 不需要连接时的方法语法 .. )。
  • @SimonWhitehead 我两个都用,但是JoinGroupJoin 我觉得用 lambda 写起来很乱。
  • 我的理解是,只要每个匿名类型的每个成员具有相同的类型和名称,它就应该可以工作。

标签: c# linq join anonymous-types inferred-type


【解决方案1】:

我注意到这里有一个明显的印刷错误:

    , ctRole => new { ctRole.IdContact, ctRole.ConatactType }

也许你的意思是这样的:

    , ctRole => new { ctRole.IdContact, ctRole.ContactType }

即使用 ContactType 而不是 ConatactType。


解决此问题后,通过评论/聊天,我们确定编译器错误仍在发生,因为用于设置多键连接的一些匿名类没有相同的成员名称。换句话说,而不是:

   , ctf => new { ctf.Contact.IdContact, ctf.ContactType }
    , ctRole => new { ctRole.ContactId, ctRole.ContactType }

需要在两个匿名类之间规范化成员名称:

   , ctf => new { ContactID = ctf.Contact.IdContact, ctf.ContactType }
    , ctRole => new { ContactID = ctRole.ContactId, ctRole.ContactType }

【讨论】:

  • 感谢您发现错字
【解决方案2】:

在 Vincent Ugenti 的帮助下,确定由于属性名称不匹配,编译器无法评估第二个连接的连接子句参数中的两个匿名类型。添加时

ContactID = 

对于两个匿名初始化程序,代码都能够编译。

.Join(GetContactRoles()
    , ctf => new { ContactID = ctf.Contact.IdContact, ctf.ContactType }
    , ctRole => new { ContactID = ctRole.ContactId, ctRole.ContactType }
    , (ctf, ctRole) => new { Contact = ctf.Contact, PrimaryInd = ctRole.IsPrimary})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多