2010-11-29 39 views
3

我想顯示的類別和子類別,像這樣:幫助用兩個表LINQ查詢

類別1個
子目錄1個
子目錄2
子類別3

類別2
子目錄5
子目錄6
子類別7

換句話說,foreach類別顯示屬於下面的每個子類別的子類別。

我的兩個表是像這樣:
類別 -
類別ID
名稱

SubCategory-
SubCategoryID
SubCategoryName
類別ID
我有類的外鍵子類別一太多。

這裏是我得到的代碼,其中顯示所有子類別foreach類別。

public void displayLinqCategory() 
{ 
    MyDataContext dbm = new MyDataContext(); 

    var q = from category in dbm.Categories 
      join subCat in dbm.SubCategories 
      on category.CategoryID equals subCat.CategoryID 
      select new { category.Name, subCat.SubCategoryName }; 

    resultSpan.InnerHtml += "<table>"; 
    foreach (var c in q) 
    { 
     resultSpan.InnerHtml += "<tr><td>" + c.Name + "</td></tr>"; 
     foreach (var s in q) 
     { 
      resultSpan.InnerHtml += "<tr><td>&nbsp;&nbsp;&nbsp;" + s.SubCategoryName + "</td></td>"; 
     } 

    } 
    resultSpan.InnerHtml += "</table>"; 
} 

回答

0

如果你添加一個into子句,它將把相關的類別分組到一個你可以很容易迭代的集合中。

方法如下:

using (var dbm = new MyDataContext()) 
{ 
    var query = dbm.Categories 
       join s in dbm.SubCategories on c.CategoryID equals s.CategoryID 
       //group the related subcategories into a collection 
       into subCollection 
       select new { Category = c, SubCategories = subCollection }; 

    foreach (var result in query) 
    { 
     //use result.Category here... 

     //now go through the subcategories for this category 
     foreach (var sub in result.Subcategories) 
     { 
      //use sub here... 
     } 
    } 
} 
+0

謝謝,這很好。是否真的有必要使用使用語句?我認爲CLR負責處理內存中未使用的數據。 – 2010-11-29 22:59:33

0

如果你在你的模型導航性能:

MyDataContext dbm = new MyDataContext(); 

var groups = dbm.SubCategories 
      .Select(x=> new { CatName = x.Category.Name, x.SubCategoryName }); 
      .GroupBy(x=>x.CatName); 

resultSpan.InnerHtml += "<table>"; 
foreach (var group in groups) 
{ 
    resultSpan.InnerHtml += "<tr><td>" + group.Key + "</td></tr>"; 
    foreach (var s in group) 
    { 
     resultSpan.InnerHtml += "<tr><td>&nbsp;&nbsp;&nbsp;" + s.SubCategoryName + "</td></td>"; 
    } 

} 
resultSpan.InnerHtml += "</table>"; 

如果你沒有添加到您的模型引用您仍然可以實現您需要使用什麼羣組加入

var groups = dbm.Categories 
    .GroupJoin(
     dbm.SubCategories, 
     x => x.CategoryID, 
     x => x.CategoryID, 
     (x, y) => new {Category = x.CategoryName, SubCategories = y.Select(s=>s.SubCategoryName)} 
); 
0

正如你所看到的,也有一些「正確」答案。以下是我該怎麼做:

// Data access belongs in its own area. Don't do it alongside HTML generation. 
// Program to an interface so you can mock this repository in unit tests. 
public interface ICategoryInfoRepository { 
    IEnumerable<CategoryInfo> GetCategoryInfo(); 
} 

public class CategoryInfo { 
    public string CategoryName {get;set;} 
    public IEnumerable<string> SubCategoryNames {get;set;} 
} 

public class CategoryInfoRepository : ICategoryInfoRepository 
{ 
    public IEnumerable<CategoryInfo> GetCategoryInfo() 
    { 
     // The 'using' clause ensures that your context will be disposed 
     // in a timely manner. 
     using (var dbm = new MyDataContext()) 
     { 
      // This query makes it pretty clear what you're selecting. 
      // The groupings are implied. 
      var q = from category in dbm.Categories 
        select new { 
         CategoryName = category.Name, 
         SubCategoryNames = 
          from subcategory in category.SubCategories 
          select subcategory.Name 
        }; 
      // Make sure all the data is in memory before disposing the context 
      return q.ToList(); 
     } 
    } 
} 
// Since all this method does is convert its input into a string, it would 
// be very easy to unit-test. 
public string GetCategoriesHtml(IEnumerable<CategoryInfo> categoryInfos) { 
    // A StringBuilder will make this HTML generation go much faster 
    var sb = new StringBuilder(); 
    // Don't use tables to represent non-tabular data. 
    // This is a list, so let's make it a list. 
    // Use CSS to format it to your liking. 
    sb.Append("<ul>"); 
    foreach(var categoryInfo in categoryInfos) 
    { 
     sb.Append("<li>").Append(categoryInfo.CategoryName).Append("<ul>"); 
     foreach(var subCategoryName in categoryInfo.SubCategoryNames) 
     { 
      sb.Append("<li>").Append(subCategoryName).Append("</li>"); 
     } 
     sb.Append("</ul></li>"); 
    } 
    sb.Append("</ul>"); 
    return sb.ToString(); 
} 

public void DisplayLinqCategory() 
{ 
    // The repository would ideally be provided via dependency injection. 
    var categoryInfos = _categoryInfoRepository.GetCategoryInfo(); 
    resultSpan.InnerHtml = GetCategoriesHtml(categoryInfos); 
} 

我做了各種「改進」,這將在一個長期的現實世界的項目中有意義。隨意忽略那些對你的特定情況沒有意義的東西。