如何在 ASP.NET MVC 中为分层数据构建自引用模型对象?

发布于 2024-09-18 07:13:54 字数 2588 浏览 8 评论 0原文

我试图了解如何为分层数据构建自引用模型。最终我将创建一个类别树。

我还没有在表格中添加任何内容。确定结构后,我将创建表格。我现有的对象定义如下:

public class Categories
{
    public Int64 catID { get; set; }
    public Int64? parentCatID { get; set; }
    public string catName { get; set; }
    public string catDescription { get; set; }
}

我的假存储库填充类别如下:

// Fake hardcoded list of categories
private static IQueryable<Categories> fakeCategories = new List<Categories> {
    new Categories { catID = 1, parentCatID = null, catName = "Root", catDescription = "" },
    new Categories { catID = 2, parentCatID = 1, catName = "Category w/subs", catDescription = "" },
    new Categories { catID = 3, parentCatID = 1, catName = "Category no subs but now has subs", catDescription = "" },
    new Categories { catID = 4, parentCatID = 2, catName = "Zub Cat", catDescription = "" },
    new Categories { catID = 5, parentCatID = 2, catName = "Sub Cat", catDescription = "" },
    new Categories { catID = 6, parentCatID = null, catName = "Another Root", catDescription = "" },
    new Categories { catID = 7, parentCatID = null, catName = "Ze German Root", catDescription = "" },
    new Categories { catID = 8, parentCatID = 3, catName = "Brand new cats", catDescription = "" },
    new Categories { catID = 9, parentCatID = 8, catName = "Brand new cats sub", catDescription = "" },
}.AsQueryable();

我一直困惑于如何使其成为一个自引用对象,我可以将其发送到视图进行显示。我在想控制器会是这样的:

public ActionResult CategoryTree()
{
    var cats = fakeRepository.Categories.ToList();
    return View(cats);
}

我不知道我是否正确地处理了这个问题。我将使用递归的自定义 HtmlHelper 方法显示类别树。

如何让 Categories 成为自引用对象?

编辑:重新表述的问题

我开始认为我问的问题超出了我的想象:-)

请检查这段代码:

[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<Category> _category;
    [Association(ThisKey = "parentCatID", Storage = "_category")]
    public Category category {
        get { return _category.Entity; }
        internal set { _category.Entity = value; }
    }
}

这段代码可以编译,我不必更改我的假存储库。但我觉得我错过了一些东西。我不确定如何测试它是否有效。我正在挑战我的知识极限。

我什至不能 100% 确定正确的问题是什么。我要去玩这个...看看我是否遇到错误或者它是否按我预期的方式工作。我可能会再次在这里编辑。

编辑 2

看来 Category.category 只是返回 null。而且,它似乎并不在任何类型的列表中。我不确定我是否正确设置了关系。

有什么想法吗?

I'm trying to understand how to build a self referencing model for hierachical data. Eventually i will be creating a category tree.

I don't anything in tables yet. After I have the structure nailed down then I will create the tables. My existing Object is defined like this:

public class Categories
{
    public Int64 catID { get; set; }
    public Int64? parentCatID { get; set; }
    public string catName { get; set; }
    public string catDescription { get; set; }
}

My fake repository populates Categories like this:

// Fake hardcoded list of categories
private static IQueryable<Categories> fakeCategories = new List<Categories> {
    new Categories { catID = 1, parentCatID = null, catName = "Root", catDescription = "" },
    new Categories { catID = 2, parentCatID = 1, catName = "Category w/subs", catDescription = "" },
    new Categories { catID = 3, parentCatID = 1, catName = "Category no subs but now has subs", catDescription = "" },
    new Categories { catID = 4, parentCatID = 2, catName = "Zub Cat", catDescription = "" },
    new Categories { catID = 5, parentCatID = 2, catName = "Sub Cat", catDescription = "" },
    new Categories { catID = 6, parentCatID = null, catName = "Another Root", catDescription = "" },
    new Categories { catID = 7, parentCatID = null, catName = "Ze German Root", catDescription = "" },
    new Categories { catID = 8, parentCatID = 3, catName = "Brand new cats", catDescription = "" },
    new Categories { catID = 9, parentCatID = 8, catName = "Brand new cats sub", catDescription = "" },
}.AsQueryable();

I am stuck on how to make this a self referencing object which I can send to a view for display. I was thinking that the controller would be something like this:

public ActionResult CategoryTree()
{
    var cats = fakeRepository.Categories.ToList();
    return View(cats);
}

I don't know if I'm approaching this correctly. I would display the category tree using a custom HtmlHelper method that recurses.

How would I get Categories to be a self referencing object?

Edit: rephrased question

I'm starting to think that I'm asking questions that are over my head :-)

Please examine this code:

[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<Category> _category;
    [Association(ThisKey = "parentCatID", Storage = "_category")]
    public Category category {
        get { return _category.Entity; }
        internal set { _category.Entity = value; }
    }
}

This code compiles and I don't have to change my fake repository. I feel like im missing something though. I'm not sure how to test this to see if it works. I'm pushing against the limits of my knowledge.

I'm not even 100% sure of what the correct question is. I'm going to go play with this... see if I get errors or if it works the way i expect. I'll probably edit here again.

Edit 2

It appears that Category.category is just returning null. And, it doesn't seem to be in a list of any type. I'm not sure if I set up the relationship correctly.

Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

萌酱 2024-09-25 07:13:54
public class Category   // an instance of the class is just ONE category
{
    public Int64 Id { get; set; }
    public Category Parent { get; set; }        // A parent link, EF will  handle this for you using an Association
    public List<Category> Children {get; set;}  // Replace this when you move to EF or L2S
    public string Name { get; set; }
    public string Description { get; set; }
}

如果您在 Visual Studio 中使用 Linq2Sql 或实体框架设计器,则可以创建一个名为“类别”的实体(或类),然后创建一个与其自身的关联。任一设计器都会自动在实体/类上创建一个集合属性,该属性允许您导航到子集合。

您的 Linq2Sql 图可能如下所示:

alt text

关联应如下所示:
alt text

然后,您的假存储库可以简单地使用 Linq2Sql 类,如下所示:-

Category root = new Category() { Name = "Root", Parent = null };
Category child1 = new Category() { Name = "Child 1", Parent = root };
Category child2 = new Category() { Name = "Child 2", Parent = root };

Linq2Sql 将“神奇地”设置“Children”为您收集的“Root”合集。

public class Category   // an instance of the class is just ONE category
{
    public Int64 Id { get; set; }
    public Category Parent { get; set; }        // A parent link, EF will  handle this for you using an Association
    public List<Category> Children {get; set;}  // Replace this when you move to EF or L2S
    public string Name { get; set; }
    public string Description { get; set; }
}

If you use the Linq2Sql or Entity Framework designer in Visual Studio instead you can create an Entity (or Class) called 'Category' and then an association back to itself. Either designer will automatically create a collection property on the entity/class that allows you to navigate to the collection of children.

Here's what your Linq2Sql diagram might look like:

alt text

And here's what the association should look like:
alt text

Your fake repository can then simply use the Linq2Sql classes like so:-

Category root = new Category() { Name = "Root", Parent = null };
Category child1 = new Category() { Name = "Child 1", Parent = root };
Category child2 = new Category() { Name = "Child 2", Parent = root };

And Linq2Sql will 'magically' set the 'Children' collection on 'Root' for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文