2010-11-29 108 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); 
} 

我做了各种“改进”,这将在一个长期的现实世界的项目中有意义。随意忽略那些对你的特定情况没有意义的东西。