ASP.NET MVC中的类别/子类别 [英] Categories/Subcategories in asp.net mvc

查看:93
本文介绍了ASP.NET MVC中的类别/子类别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在建立像 https://www.etsy.com/这样的市场.而且我们在对列表进行分类时遇到了问题.我们想将清单中的项目分为3个等级,例如,它必须按以下顺序进行分类:

We are making a marketplace like https://www.etsy.com/. And we have a problem in categorising the listings. We want to categories the item in the Listing in 3 levels, f.ex it has to be categories in this order:

 Category 1 
    Sub Category 1.1
       Sub Category 1.1.1

重要的一件事是,当您选择类别时,请输入f.ex.电子产品,那么在子类别中,您只能看到PC,智能手机,电视等内容.

One of the important thing is that when you choose a category, f.ex. Electronics, then in the subcategory you can only see stuff like pc, smartphone, tv etc.

这就是我们现在拥有的

 public class Listing
{
    public int ListingId { get; set; }
    public String Name { get; set; }

    public int Subcategory2Id { get; set; }
    public virtual Subcategory2 Subcategory2 { get; set; }
}



public class Category
{
    public int CategoryId { get; set; }
    public String CategoryName { get; set; }

    public virtual ICollection<Subcategory1> Subcategory1s { get; set; }
}



public class Subcategory1
{
    public int Subcategory1Id { get; set; }
    public String Subcategory1Name { get; set; }

    public int CategoryId { get; set; }
    public virtual Category Categories { get; set; }

    public virtual ICollection<Subcategory2> Subcategory2s { get; set; }
}



public class Subcategory2
{
    public int Subcategory2Id { get; set; }
    public String Subcategory2Name { get; set; }

    public int Subcategory1Id { get; set; }
    public virtual Subcategory1 Subcategory1s { get; set; }

    public virtual ICollection<Listing> Listings { get; set; }
}

,在IdentityModels-ApplicationDbContext中,我们拥有

and in the IdentityModels-ApplicationDbContext we have

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Listing> Listings { get; set; }
    public DbSet<Category> Categories { get; set; }
    public DbSet<Subcategory1> Subcategory1s { get; set; }
    public DbSet<Subcategory2> Subcategory2s { get; set; }

    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

问题是我们不确定这是否是正确的方法,而且我们不知道该如何进行,意思是,当您创建列表时,必须有3个下拉列表,选择相应的类别.因此,首先选择类别,然后可以选择子类别1等...

推荐答案

您绝对不应拥有多个类别/子类别实体.一个类别可以有一个父类别,也可以有一个子类别,但是它们都是类别".

You should absolutely not have multiple category/subcategory entities. A category can have a parent and it can have children, but they're all "categories".

public class Category
{
    public int Id { get; set; }

    public int? ParentId { get; set; }
    public virtual Category Parent { get; set; }

    public virtual ICollection<Category> Children { get; set; }
}

ParentId可为空,因为顶级类别没有父级.

ParentId is nullable, because top-level categories have no parent.

实体框架易于因自引用关系而感到困惑,因此您可能需要一些流利的配置来帮助解决问题:

Entity Framework tends to get confused by self-referencing relationships, so you might need a little fluent config to help it out:

public class Category
{
    // properties

    public class Mapping : EntityTypeConfiguration<Category>
    {
        public class Mapping()
        {
            HasOptional(m => m.Parent).WithMany(m => m.Children);
        }
    }
}

然后,在您的上下文中:

Then, in your context:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new Category.Mapping());
}

所有这些都准备就绪,当您处于电子"类别时,只需遍历其Children属性即可显示子类别.

With all that in place, when you're in your "Electronics" category, you'd show the subcategories simply by iterating over it's Children property.

更新

如果您需要完整的层次结构,而不是一次只需要一个层次,则有两种选择.首先,您可以在查询时仅包含多个级别:

If you need the full hierarchy rather than just one level at a time, you have a couple of options. First, you can just include multiple levels when querying:

db.Categories.Include("Children.Children");

但是,这并不是很有效,我绝对不建议比大专生更深入地学习.但是,这就是您要的全部,因此这仍然是一种可行的方法.

That's not highly efficient, though, and I definitely would not recommend delving much deeper than tertiary children. However, that's all you're asking for, so this is still a workable method.

第二,您可以创建一个存储过程来遍历您的层次结构.稍微复杂一点,但是结合使用WITHUNION ALL,您可以创建层次结构的平面表示,然后递归使用LINQ的GroupBy将其重新构造为层次结构.

Second, you can create a stored procedure to walk the hierarchical structure for you. It's a little more complex, but with a combination of WITH and UNION ALL, you can create a flat representation of the hierarchy and then recursively use LINQ's GroupBy to work it back into a hierarchical structure.

@Hackerman建议使用HIERARCHYID,这是最后一个潜在的第三种选择,但不幸的是,要这样做,您必须从EF上下文中完全删除Category,这也意味着也要删除与它的任何直接关系.要将产品与类别相关联,您只能存储ID(而不是作为外键),然后在第二步中使用该ID手动查找类别.不幸的是,尽管此解决方案使层次结构的处理变得更加容易,但使其他所有事情变得更加困难.无论哪种方式,都取决于您.

There's a final potential third option in @Hackerman's recommendation of using HIERARCHYID, but unfortunately, to do that, you must completely remove Category from your EF context, which also means removing any direct relationships to it, as well. To relate a product to a category, you could only store the id (not as a foreign key), and then use that id to manually lookup the category in a second step. Unfortunately, while this solution makes dealing the the hierarchy easier, it makes doing everything else more difficult. Either way, it's up to you, though.

这篇关于ASP.NET MVC中的类别/子类别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆