0

In C#, I'm attempting to do multiple extension-method joins, in which the second join is with an enumerable of an anonymous type produced by the first join:

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 and ctf.Contact is of Type Contact.

I am, however, getting the following error when attempting to compile:

The type arguments for method 'System.Linq.Enumerable.Join...' cannot be inferred from the usage. Try specifying the type argument explicitly.

Is there a way to get around this error without having to create an actual class for the anonymous type from the first join? Are there other options that I am not considering?

12
  • I would recommend writing the linq statement with query syntax instead as it is both easier to read and write (in my opinion). Commented Mar 23, 2015 at 22:09
  • I much prefer the extension methods, I personally find them much easier to read. Also a nice feature of using extension methods is that you can break these into multiple lines of code in order to get a clearer error message from the compiler. Commented Mar 23, 2015 at 22:10
  • Ahhh... that old argument. "Method syntax vs. Query Syntax" (I'm a query syntax person for Joins .. method syntax when no joins are required .. ). Commented Mar 23, 2015 at 22:11
  • @SimonWhitehead I do use both but Join and GroupJoin I feel is quite messy to write in lambda. Commented Mar 23, 2015 at 22:14
  • 2
    My understanding is that should work as long as each member of each anonymous type has the same type and name. Commented Mar 23, 2015 at 23:00

2 Answers 2

3

I notice an apparent typographical error here:

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

where perhaps you mean this:

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

i.e. use ContactType instead of ConatactType.


After this was resolved, through comment / chat we determined that compiler errors were still occurring because some of the anonymous classes being used to set up the multi-key joins did not have the same member names. In other words, instead of:

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

The member names needed to be normalized between the two anyonymous classes:

   , ctf => new { ContactID = ctf.Contact.IdContact, ctf.ContactType }
    , ctRole => new { ContactID = ctRole.ContactId, ctRole.ContactType }
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for catching the typo
0

With the help of Vincent Ugenti, it was determined that the compiler could not evaluate the two anonymous types in the join clause arguments for the second join due to a mismatch in property names. When adding

ContactID = 

to both of the anonymous initializers, the code was able to compile.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.