下面我围绕现有的Max
扩展方法编写了一个简单的包装器,它允许您提供一个空源(您正在谈论的表)。
它不会抛出异常,而是只返回默认值零。
原来的
public static class Extensions
{
public static int MaxId<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
if (source.Any())
{
return source.Max(selector);
}
return 0;
}
}
这是我的尝试,正如 Timothy 所指出的,这实际上是相当低劣的。这是因为序列将被枚举两次。一次调用Any
时检查源序列是否有任何元素,再次调用Max
.
改进
public static class Extensions
{
public static int MaxId<TSource>(this IQueryable<TSource> source, Func<TSource, int> selector)
{
return source.Select(selector).DefaultIfEmpty(0).Max();
}
}
这个实现使用了 Timothy 的方法。通过调用DefaultIfEmpty
,我们利用了延迟执行,并且仅在调用时枚举序列Max
。此外,我们现在使用IQueryable
代替IEnumerable
which 意味着我们不必在调用此方法之前枚举源。正如斯科特所说,如果您需要它,您也可以创建一个使用的重载IEnumerable
。
为了使用扩展方法,你只需要提供一个返回源类型 id 的委托,就像你为Max
.
public class Program
{
YourContext context = new YourContext();
public int MaxStudentId()
{
return context.Student.MaxId(s => s.Id);
}
public static void Main(string[] args)
{
Console.WriteLine("Max student id: {0}", MaxStudentId());
}
}
public static class Extensions
{
public static int MaxId<TSource>(this IQueryable<TSource> source, Func<TSource, int> selector)
{
return source.Select(selector).DefaultIfEmpty(0).Max();
}
}