I am trying to find a better way to write an effective JOIN using LINQ and Lambda expressions, hopefully using a Join, to work with the following types:
public class Patent
{
public string Title { get; set; }
public string YearOfPublication { get; set; }
public long[] InventorIds { get; set; }
}
public class Inventor
{
public long Id { get; set; }
public string Name { get; set; }
}
The subsequent data is being created as such:
public static class PatentData
{
public static readonly Inventor[] Inventors = new Inventor[]
{
new Inventor(){
Name="Benjamin Franklin", Id=1 },
new Inventor(){
Name="Orville Wright", Id=2},
new Inventor(){
Name="Wilbur Wright", Id=3}
};
public static readonly Patent[] Patents = new Patent[]
{
new Patent(){
Title="Bifocals", YearOfPublication="1784",
InventorIds=new long[] {1}},
new Patent(){
Title="Flying machine", YearOfPublication="1903",
InventorIds=new long[] {2,3}}
};
}
To iterate through all the inventors for a particular patent, I am using the following code below.
IEnumerable<Patent> patents = PatentData.Patents;
IEnumerable<Inventor> inventors = PatentData.Inventors;
foreach(Patent p in patents)
{
var iall = inventors.Where(i => p.InventorIds.Contains(i.Id));
foreach (Inventor i in iall)
{
Debug.WriteLine(p.Title + ": " + i.Id);
}
}
Although the code above works fine, I would really like to use a LINQ Join statement. The problem, obviously, is that the LINQ Join statement will grumble about the different types (long and long[]) which are primary and foreign keys respectively.
The code that I would have preferred to use of which I can’t seem to get working, is follows:
Patent [] patents = PatentData.Patents;
Inventor [] inventors = PatentData.Inventors;
var result = patents.Join(inventors, patent => patent.InventorIds, inventor => inventor.Id, (patent, inventor) => new
{
patent.Title,
inventor.Name
});
This is failing, quite rightly, with the following error:
error CS0411: The type arguments for method ‘System.Linq.Enumerable.Join(System.Collections.Generic.IEnumerable, System.Collections.Generic.IEnumerable, System.Func, System.Func, System.Func)’ cannot be inferred from the usage. Try specifying the type arguments explicitly.
So, my question is:
How can I repair the code that has the error to work with the Join statement when used in conjunction with the two types; Patent and Inventor – without modifying the types at all? Is it even possible?
I appreciate that I can change the types so that they are better structured, but humour me for a moment.
You need a join for each individual patent:
Of course, if you could avoid using the
Idpart of your model and instead associate inventors of a patent directly withInventorobjects, that would be simpler.