【问题标题】:LINQ error on join: "CS1061 'Guid' doesn't contain a definition for <column name>连接时出现 LINQ 错误:“CS1061 'Guid' 不包含 <column name> 的定义>
【发布时间】:2018-05-01 21:38:07
【问题描述】:

我正在学习 LINQ,使用 LINQPAD 进行测试,并且遇到了我无法解释的 JOINing 错误。我搜索了这个论坛,我能找到的最接近接受的答案是我加入的键不是相同的数据类型,但我可以绝对保证它们是(它们都是 GUID)。

这里是失败的代码,尽管在线参考和教程告诉我我写得正确:

var Table1 = (from fis in FinancialInstitutionExaminers
              select fis.InvitedByID).Distinct();

var Table2 = (from c in Contacts
              select new {c.ID, c.FirstName, c.LastName });



var JoinedTables2 = Table1.Join(Table2,
                                k1 => k1.InvitedByID,  // This causes failure
                                k2 => k2.ID,
                                (k1, k2) => 
                                        new {
                                                //ConID = k1.InvitedByID,
                                                ConFirstName = k2.FirstName,
                                                ConLastName = k2.LastName
                                            });                             
JoinedTables2.Dump();

问题在于 k1 => k1.InvitedByID 行。当我指定列“InvitedByID”时,我收到错误消息“CS1061 'Guid' 不包含 'InvitedByID' 的定义。

InvitedByID 确实存在于我的数据源中,并且它与我要加入的列的类型相同(ID,在我的加入中由 k2=> k2.ID 指定)。两列都是 GUID。

这就是让我震惊的地方。如果我如下修改代码,从 k1 => k1.InvitedBy 中删除 InvitedBy,则代码有效。这让我很困惑。我不明白 (1) 为什么我不能在连接中显式使用列名,以及 (2) 没有它,代码如何可能工作(我可以看到 LINQ 如何推断它应该加入为Table1选择的唯一列,但同样,如果该列的数据类型没有问题,为什么我不能明确命名?)

这行得通:

var Table1 = (from fis in FinancialInstitutionExaminers
              select fis.InvitedByID).Distinct();

var Table2 = (from c in Contacts
              select new {c.ID, c.FirstName, c.LastName });



var JoinedTables2 = Table1.Join(Table2,
                                k1 => k1,   // Note I removed InvitedBy
                                k2 => k2.ID,
                                (k1, k2) => 
                                        new {
                                                //ConID = k1.InvitedByID,
                                                ConFirstName = k2.FirstName,
                                                ConLastName = k2.LastName
                                            });                             
JoinedTables2.Dump();

【问题讨论】:

    标签: linq linqpad


    【解决方案1】:

    您的投影(使用select)不正确。您似乎正在尝试访问IEnumerable&lt;T&gt; FinancialInstitutionExaminersT 的任何类型的对象的属性InvitedByID(用您使用的任何类型填写此T,因为我看不到您的代码的那部分)。该属性返回GUID。因此,Table1 的类型为 IEnumerable&lt;GUID&gt;,而不是类型 IEnumerable&lt;T&gt;。虽然var 可能很有用,但过度使用它通常会导致此类错误。

    试试:

    var Table1 = FinancialInstitutionExaminers.Distinct();
    
    var Table2 = (from c in Contacts
              select new {c.ID, c.FirstName, c.LastName });
    
    
    
    var JoinedTables2 = Table1.Join(Table2,
                                k1 => k1.InvitedByID, 
                                k2 => k2.ID,
                                (k1, k2) => 
                                        new {
                                                ConID = k1.InvitedByID,
                                                ConFirstName = k2.FirstName,
                                                ConLastName = k2.LastName
                                            });                             
    JoinedTables2.Dump();
    

    【讨论】:

    • 完美的解决方案 kotval,我同意过度使用“var”。您对它如何导致错误的解释是一个很好的学习点。多年来,我一直在实践不惜一切代价避免使用“var”,但我现在在一家严重依赖它的商店里,而且我正在学习的教程使用它,所以我掉进了那个陷阱。希望其他像我这样落入这个陷阱的新手会看到你的答案和 sgmoore 的澄清,并因此得到更好的理解和更清晰的代码。
    【解决方案2】:

    Kotval 的答案是完全正确的,但你也可以像这样写第一部分

    var Table1 = (from fis in FinancialInstitutionExaminers
               select new { fis.InvitedByID } ).Distinct();
    

    不同之处在于,当您使用k1 =&gt; 时,k1 将是一个包含名为 InvitedByID 的 Guid 的对象,因此您可以说 k1 =&gt; k1.InvitedByID 而在您的代码中 k1 是 Guid,您必须说 k1 =&gt; k1

    【讨论】:

    • 精彩的澄清 sgmoore。我真的很喜欢你对第一部分的重写,因为我可以在选择中明确看到 InvitedBy 列。恕我直言,这是更清晰的代码。我希望我可以将两个答案标记为已接受:-(
    猜你喜欢
    • 2011-08-21
    • 2023-03-20
    • 2018-04-11
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多