我想要这样的事情:
public int NumberStudent()
{
int i = 0;
if (db.Tbl_Student.ToList().Count() > 0)
i = db. Tbl_Student.Max(d => d.id);
return i;
}
但是,我想在任何桌子上使用它:
public int FindMaxId(string TableName)
{
int i =0;
if ('db.'+TableName+'.ToList().Count() > 0' )
i = db. TableName.Max(d => d.id);
return i ;
}
我知道这是错的,但我不知道该怎么做。
答案 0 :(得分:9)
您可以使用IEnumerable
/ IQueryable
扩展程序DefaultIfEmpty
进行此操作。
var maxId = db.Tbl_Student.Select(x => x.Id).DefaultIfEmpty(0).Max();
一般来说,如果你Q.DefaultIfEmpty(D)
,则表示:
如果
Q
不为空,请给我Q
;否则,请给我[ D ]
。
答案 1 :(得分:4)
下面我写了一个围绕现有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;
}
}
这是我的尝试,正如提摩太所指出的那样,其实是相当低劣的。这是因为序列将被枚举两次。在调用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
,我们正在使用deferred execution,并且只有在调用Max
时才会枚举序列。此外,我们现在使用IQueryable
而不是IEnumerable
,这意味着我们在调用此方法之前不必枚举源代码。正如斯科特所说,如果你需要它,你也可以创建一个使用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();
}
}
答案 2 :(得分:0)
db.Tbl_Student.Aggregate(0, (maxId, s) => Math.Max(maxId, s.Id))
或
db.Tbl_Student.Max(s => (int?)s.Id) ?? 0