tags:

views:

75

answers:

1

I'm trying to move the following query to Linq-to-sql, is it possible?

select * from (
Select top (@Percent) percent with ties *
from(
 Select distinct
   LoanNumber as LoanNo
 From CHE 
 Left Join RecordingInfo as Rec
 On CHE.LoanNumber = Rec.LoanNo
 Where Channel = 'LINX'
  and CHE.Doc in ('MTG','MOD')
  and Rec.LoanNo is null
  and LoanNumber >= '@LoanNo'
) A
order by LoanNo @Order
) B
order by LoanNo

I have not seen anyway to do with ties in linq.

+2  A: 

I think something like this will work for you.

public static IQueryable<T> TopPercentWithTies<T, TKey>(this IOrderedQueryable<T> query, Expression<Func<T, TKey>> groupByExpression, double percent)
{
    var groupedQuery = query.GroupBy(groupByExpression);
    int numberToTake = groupedQuery.Count() * percent / 100;
    return groupedQuery.Take(numberToTake).SelectMany(t => t);
}

I only tested it with IEnumerable, so I don't know for sure that it'll work properly with IQueryable. I also sorted the list before calling TopPercentWithTies().

Here's the code I used to test it.

int percent = 50;
var people = new []
{
    new { Age = 99, Name = "Adam" },
    new { Age = 99, Name = "Andrew" },
    new { Age = 89, Name = "Bob" },
    new { Age = 50, Name = "Cecil" },
    new { Age = 50, Name = "Doug" },
    new { Age = 50, Name = "Everett" },
    new { Age = 35, Name = "Frank" },
    new { Age = 25, Name = "Greg" },
    new { Age = 15, Name = "Hank" }
};
var sortedPeople = people.AsQueryable().OrderByDescending(person => person.Age);
var results = sortedPeople.TopPercentWithTies(person => person.Age, percent);
foreach (var person in results)
    Console.WriteLine(person);

Hope it helps or at least gets you in the right direction. You may want to tweak the logic for calculating numberToTake.

Ecyrb
very nice. although I would expect it would be an extension of IOrderedQueryable.
Maslow
Oh sweet. I didn't know about IOrderedQueryable. I've updated the code.
Ecyrb