2013-08-30 20 views
0

我想是這樣的:如何查找任何表的最大ID。

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 ; 
    } 

我知道這是錯的,但我不知道該怎麼辦它。

+2

'.ToList()。COUNT()> 0',很有可能與'。任何()代替'它會提高你的表現太,因爲它不需要枚舉兩次表。 –

回答

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; 
    } 
} 

這是我的嘗試,這是由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(); 
    } 
} 

此實現使用提摩太的做法。通過調用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(); 
    } 
} 
+0

看看我的答案。有一個鮮爲人知的LINQ方法已經存在。 –

+0

另一個很好的方法,當然。這隻貓可以用很多方式剝皮!Upvoted :) –

+1

關鍵是你的'MaxId'幫手方法的主體可以簡單地用'return source.Select(選擇器).DefaultIfEmpty(0).Max();'代替。贊成將現有操作從頭開始製作新的操作。你的'MaxId'方法實際上會枚舉'source'兩次。 –

9

您可以使用IEnumerable/IQueryable擴展方法DefaultIfEmpty這一點。

var maxId = db.Tbl_Student.Select(x => x.Id).DefaultIfEmpty(0).Max(); 

在一般情況下,如果你這樣做Q.DefaultIfEmpty(D),它意味着:

如果Q不是空的,給我Q;否則,給我[ D ]

+0

沒有評論,沒有什麼比較讚的。 –

+0

啊,我的壞..我現在看到,這將實際上適用於任何表,我的壞。 +1 –

+0

'var maxId = db.Tbl_Student.Max(s =>(int?)s.Id)?? 0' – Vladimir

0

db.Tbl_Student.Aggregate(0, (maxId, s) => Math.Max(maxId, s.Id))

db.Tbl_Student.Max(s => (int?)s.Id) ?? 0

+0

謝謝。但我想用它來做任何表。我想傳遞表名並返回maxid。 – niknaz