I need some help with Linq self-join.
I have the following classs:
public class Owner
{
public string OwnerId {get;set;}
public string Name {get;set;}
public string Area {get;set;}
public string City {get;set;}
public string Sex {get;set;}
public List<Dog> dog {get;set;}
}
And table….
ID OwnerId OwnerName TypeId TypeName TypeValue TypeCodeId
1 1 John 1 Area United States 440
2 1 John 2 City Los-Angeles 221
3 1 John 3 Sex Female 122
4 2 Mary 1 Area Mexico 321
4 2 Mary 2 City Cancun 345
............................................................
I need to parse results of table1 into list of owners the fastest way possible.
Note: Type can be null, but I still need to show that owner (So, I assume left join should work).
Here’s What I do. (owners is a webservice class that contains table1 results)
public IEnumerable<Owner> GetOwners() {
return (from owner in owners
join area in owners into owner_area
from oa in owner_area.DefaultIfEmpty()
join City in owners into owner_city
from oc in owner_city.DefaultIfEmpty()
join sex in owners into owner_sex
from os in owner_sex.DefaultIfEmpty()
where oa.TypeId == 1 && oc.TypeId ==2 && os.TypeId ==3
select new Owner() {OwnerId = owner.OwnerId,
Name = owner.Name,
Area = oa.TypeValue,
City = oc.TypeValue,
Sex = os.TypeValue}).Distinct();
}
This query has several issues:
- It returns multiple results and distinct does not work as expected
- I’ve tried to use GroupBy but it says that cannot implicitly convert Owner into
IEnumerable <int, Owner> - It is super slow
How can I get distinct record with self join and improve performance?
Thanks
UPDATE:
Thank you guys for your ansewers, testing now, but I figured out that I forgot to supply one more thing. I’ve added a new column called TypeCodeId to the table layout(see above)
User can filter values based on their selection. So, I have TypeCodeId + TypeValue dictionaries for Area, City and Sex. All of those parameters are optional (If the user didn’t select any, I just show them all records.
So, Assume that the user has selected filter Area: Unites States and filter City: Los Angeles
them my query would look like this:
Select Projects where Area equals United States(440) and City equals Los Angeles(221)
If Only Area:Mexico was selected then my query would read something like this:
Select Projects where Area equals Mexico(321)
I’m not sure how to do optional where clauses with what you’ve provided in the examples.
For best performance if think this is the way to do it.
To get even a little more performance you can write an
IEqualityComparerclass that only compares int OwnerId and send it into theDistinctfunction