مساعدة في استعلام طاولة LINQ
-
29-09-2019 - |
سؤال
أريد أن أعرض الفئات والفئات الفرعية مثل:
الفئة 1
الفئة الفرعية 1
الفئة الفرعية 2
الفئة الفرعية 3
الفئة 2
الفئة الفرعية 5
الفئة الفرعية 6
الفئة الفرعية 7
بمعنى آخر ، فئة Foreach ، تعرض الفئات الفرعية التي تنتمي إلى كل واحدة تحتها.
طاولاتي مثل هكذا:
فئة-
معرف الفئة
اسم
تصنيف فرعي-
الفئة الفرعية
الاسم الفرعي
معرف الفئة
لدي مفتاح خارجي من الفئة إلى الفئة الفرعية واحدة إلى كثيرين.
هنا حيث حصلت على الكود ، والتي تعرض جميع الفئات الفرعية 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> " + s.SubCategoryName + "</td></td>";
}
}
resultSpan.InnerHtml += "</table>";
}
المحلول
إذا قمت بإضافة جملة إلى جملة ، فستقوم بتجميع الفئات ذات الصلة في مجموعة يمكنك تكرارها بسهولة.
إليك الطريقة:
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...
}
}
}
نصائح أخرى
إذا كان لديك خصائص ملاحية في النموذج الخاص بك:
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> " + 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)}
);
كما ترون ، هناك عدد من الإجابات "الصحيحة". إليك كيف سأفعل ذلك:
// 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);
}
لقد قمت بإجراء "تحسينات" مختلفة من شأنها أن تكون منطقية في مشروع العالم الحقيقي على المدى الطويل. لا تتردد في تجاهل تلك التي لا معنى لها لموقفك الخاص.