Entity Framework 核心中无重复的有序集合

Ordered collection without duplicates in Entity Framework Core

我需要存储我的实体中已订购的元素列表。但是因为它是多对多关系,而不是一对多关系,所以我不能只为我的子实体添加排序索引。例如考虑这些实体:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Dish> FavoriteDishes { get; set; }
}

public class Dish
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Person> People { get; set; }
}

如您所见,这是一个多对多的关系,其中一个人有一个他们喜欢吃的最喜欢的菜的列表,每道菜都有一个喜欢这道菜的人的列表。

当要考虑最喜欢的菜肴列表时会出现问题,例如一个排名,比如前十名的榜单。现在需要有一种方法来为这些元素创建一个已定义但用户可编辑的顺序。此外,列表不应包含重复项。

每道菜都属于多人,我不能只在此处添加索引 属性。我考虑过使用 List<Tuple<int,Dish>> 之类的东西来存储每道菜的索引,但我不知道如何设置它,因为我对 Entity Framework Core 没有太多经验。

对于这种多对多关系的问题,我找不到太多相关信息。我所能找到的只是一对多(例如将索引 属性 添加到子实体)或返回按某些 属性 排序的列表(例如 get => SomeList.Sort(...))。

我现在能想到的唯一方法是将 index/id 对列表存储在未映射的 属性 中,并将其存储为字符串以在 [=29] 时保持顺序=] 它来自数据库。但这看起来确实很乏味,尤其是在试图使这些与用户编辑的实际列表保持同步时。手动为多对多关系实现 PersonDish 元素而不是使用自动生成的元素似乎也不是很简单(同样,使用 ef 的经验也不多)。而且这两种方法都必须为每个需要排序的列表 属性 完成,这使得它的可扩展性不强。

关于如何解决这个问题有什么提示或建议吗?

我认为您需要明确定义第三个 table 并添加评级 属性

public class PersonDish
{
    public int PersonId { get; set; }
    public int DishId { get; set; }

    public int? Rating {get; set;}

    public  virtual Person Person { get; set; }
    public virtual Dish Dish { get; set; }
}

public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual List<PersonDish> PersonDishes { get; set; }
    }

public class Dish
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public virtual List<PersonDish> PersonDishes { get; set; }
    }

和 dbcontext

            modelBuilder.Entity<PersonDish>( b =>
            {

                b.HasKey( k=> new { k.PersonId, k.DishId });

                b.HasIndex(i=> i.PersonId);
                b.HasIndex(i=> i.DishId);

                b.HasOne( a=> a.Dish)
                     .WithMany(m=> m.PersonDishes)
                    .HasForeignKey(d => d.DishId)
                    .OnDelete(DeleteBehavior.ClientSetNull)
                    .IsRequired();

                b.HasOne(a=>a.Person)
                               .WithMany(m=>m.PersonDishes)
                                .HasForeignKey(k=> k.PersonId)
                                .OnDelete(DeleteBehavior.ClientSetNull)
                                .IsRequired();
            });