3

我想像这样显示类别和子类别:

类别 1
子类别 1
子类别 2
子类别 3

类别 2
子类别 5
子类别 6
子类别 7

换句话说,对于每个类别,在下面显示属于每个类别的子类别。

我的两个表是这样的:
Category-
CategoryID
Name

SubCategory-
SubCategoryID
SubCategoryName
CategoryID
我有一个从类别到子类别的外键一对多。

这是我在代码中的位置,它显示了每个类别的所有子类别。

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

3 回答 3

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

如果您没有添加对模型的引用,您仍然可以使用 GroupJoin 实现您所需要的

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)}
);
于 2010-11-29T22:28:23.133 回答
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...
        }   
    }
}
于 2010-11-29T22:28:37.150 回答
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);
}

我已经做出了各种“改进”,这些“改进”在一个长期的、现实世界的项目中是有意义的。随意忽略对您的特定情况没有意义的那些。

于 2010-11-29T23:24:48.543 回答