我正在尝试使用linqTOsql映射创建自引用对象。到目前为止,我绝对是在我脑海里。这是我的代码:
[Table]
public class Category
{
[Column(IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)]
public Int64 catID { get; set; }
public Int64 parentCatID { get; set; }
public string catName { get; set; }
public string catDescription { get; set; }
internal EntityRef<IEnumerable<Category>> _category;
[Association(ThisKey = "parentCatID", Storage = "_category")]
public IEnumerable<Category> category {
get { return _category.Entity; }
set { _category.Entity = value; }
}
}
我的fakeRepository
定义如下:
// Fake hardcoded list of categories
private static IQueryable<Category> fakeCategories = new List<Category> {
new Category { catID = 1, parentCatID = 0, catName = "Root", catDescription = "" },
new Category { catID = 2, parentCatID = 1, catName = "Category w/subs", catDescription = "" },
new Category { catID = 3, parentCatID = 1, catName = "Category no subs but now has subs", catDescription = "" },
new Category { catID = 4, parentCatID = 2, catName = "Zub Cat", catDescription = "" },
new Category { catID = 5, parentCatID = 2, catName = "Sub Cat", catDescription = "" },
new Category { catID = 6, parentCatID = 0, catName = "Another Root", catDescription = "" },
new Category { catID = 7, parentCatID = 0, catName = "Ze German Root", catDescription = "" },
new Category { catID = 8, parentCatID = 3, catName = "Brand new cats", catDescription = "" },
new Category { catID = 9, parentCatID = 8, catName = "Brand new cats sub", catDescription = "" },
}.AsQueryable();
我将Category
传递给视图:
public ActionResult CategoryTree()
{
IQueryable<Category> cats = genesisRepository.Category
.Where(x => x.parentCatID == 0)
.OrderBy(x => x.catName);
return View(cats);
}
我遇到的问题是所有这些都会编译,但我没有得到超出根类别的任何内容。 Model[0].category
返回null。
我的自引用对象出了什么问题?
我想知道它是否无效,因为我的fakeRepository
中没有真正的linq-to-sql数据上下文。如果是这样的话,还有办法解决吗?如果没有与数据库的连接,我可以让它工作吗?
答案 0 :(得分:1)
Linq-to-Sql为您完成所有连接,并根据您在模型中设置的属性(及其属性)设置相关集合。
我不知道如何在没有数据库连接的情况下实现这一目标,因为internal EntityRef<IEnumerable<Category>> _category;
对我来说完全陌生 - 我更像是POCO模型类型的人。
快速谷歌之后,我发现了这个 - How to: Map Database Relationships (LINQ to SQL)
您可以将模型更改为:
[Column(IsPrimaryKey=true, IsDbGenerated=true, AutoSync=AutoSync.OnInsert)]
public Int64 CatId { get; set; }
[Column]
public Int64 ParentCatId { get; set; }
[Column]
public string CatName { get; set; }
[Column]
public string CatDescription { get; set; }
private EntitySet<Category> _ChildCategories;
[Association(Storage = "_ChildCategories", OtherKey = "ParentCatId")]
public EntitySet<Category> ChildCategories
{
get { return this._ChildCategories; }
set { this._ChildCategories.Assign(value); }
}
private EntityRef<Category> _ParentCategory;
[Association(Storage = "_ParentCategory", ThisKey = "ParentCatId")]
public Category ParentCategory
{
get { return this._ParentCategory.Entity; }
set { this._ParentCategory.Entity = value; }
}
现在,因为您的ChildCategories
属于EntitySet<Category>
类型(继承自IList<T>
),您应该能够自己连接虚假关系。
所以你可以这样做:
private static IQueryable<Category> GetFakeCategories()
{
var categories = new List<Category> {
new Category { CatId = 1, ParentCatId = 0, CatName = "Root", CatDescription = "" },
new Category { CatId = 2, ParentCatId = 1, CatName = "Category w/subs", CatDescription = "" },
//Blah
new Category { CatId = 8, ParentCatId = 3, CatName = "Brand new cats", CatDescription = "" },
new Category { CatId = 9, ParentCatId = 8, CatName = "Brand new cats sub", CatDescription = "" }
};
//Loop over the categories to fake the relationships
foreach (var category in categories)
{
category.ChildCategories = new EntitySet<Category>(); //new up the collection
foreach (var subLoopCategory in categories)
{
if (category.ParentCatId == subLoopCategory.CatId)
category.ParentCategory = subLoopCategory;
if (category.Id == subLoopCategory.ParentCatId)
category.ChildCategories.Add(subLoopCategory);
}
}
return categoies.AsQueryable();
}
至少在我脑海中起作用......: - )
HTHS,
查尔斯
编辑:回复:关于_childCategories
上的空引用的评论如下。
您可以将模型更改为:
private EntitySet<Category> _ChildCategories = new EntitySet<Category>();
答案 1 :(得分:0)
它应该是null。你得到的所有类别的ParentId都是0 ...而且你没有Id为0的孩子。所以这对我来说似乎是正确的。
它没有显示任何子类别,因为它没有要显示的子类别。试试这个:
IQueryable<Category> cats = genesisRepository.Category
.Where(x => x.parentCatID != 0)
.OrderBy(x => x.catName);
parentCatId需要指向有效的CatId才能将其作为子类别。此查询应该为您提供子类别的所有类别。