简体   繁体   中英

Using LINQ to SQL to get distinct value of an IQueryable resultset

I am using LINQ to SQL (through a DBML) that I need to limit and I am having an issue. I am using dynamic LINQ and sending in variables that are determined previously by the end user. I have a VIEW in the db that holds (via left outer joins) data from the main db table and 5 tables connecting to it. Because I am (and have to be) using dynamic LINQ the result set from the BD must be .AsQueryable() thus createing an IQueryable result set. Here is an example of what it is doing:

Lets say the view holds car information (Make, Model, Year, Color, Milage, service records). If the user puts in that they want to see all FORD Mustangs that have been serviced this year, the result set would come back as such

[uniqueID - 1][Ford][Mustang][1/1/2012](service date)
[uniqueID - 1][Ford][Mustang][2/1/2012](service date)
[uniqueID - 1][Ford][Mustang][3/1/2012](service date)
[uniqueID - 1][Ford][Mustang][4/1/2012](service date)

Which is fine, lets assume that this particular mustang has had 4 services done this year.

However if the user puts in to just see all black FORDs then it comes back

[uniqueID - 1][Ford][Mustang]
[uniqueID - 1][Ford][Mustang]
[uniqueID - 1][Ford][Mustang]
[uniqueID - 1][Ford][Mustang]
[uniqueID - 2][Ford][Taurus]

It is returning a row for each service, even though the service would be null and the IQueryable that is returned has a .Distinct().

return data.Distinct().OrderBy(strOrderBy).Select("New(" + strItems + ")");

What I need to be able to do, is take that IQueryable and get the distinct values from it, since the variables coming in are dynamic, I am not sure how to do this.

Which ORM are you using? Different ORMs have different behaviours, particularly if the ORM doesn't send a "distinct" call in the sql it sends to the DB.

Is your "data" variable resolved before running that line? If so, you're doing a Distinct on Linq to Objects, not Linq to SQL

From your example, the most direct thing to do is to implement an IEqualityComparer for your query with the second Distinct overload. It'll look something like this:

return data.Distinct(new YourEqualityComparer()).OrderBy(strOrderBy).Select("New(" + strItems + ")");

Do note, if you want your ordering to be done server side, you'll have to push the OrderBy call before the distinct.

Here are some useful links related to this topic:

http://msdn.microsoft.com/en-us/library/ms132151.aspx http://blog.lavablast.com/post/2010/05/05/Lambda-IEqualityComparer3cT3e.aspx http://www.codeproject.com/Articles/94272/A-Generic-IEqualityComparer-for-Linq-Distinct

I suspect the .Distinct() is being performed ont he entire row of data, and since they all have different service dates, none are duplicated, so are not eliminated by the .Distinct() .

You could try changing the order of the methods to:

return data.OrderBy(strOrderBy).Select("New(" + strItems + ")").Distinct();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM