代码优先于db上下文中没有实体的多对多关系 [英] Code-First many-to-many relationship with no entity in db context

查看:59
本文介绍了代码优先于db上下文中没有实体的多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们接管了一个项目,其中包含一个由两个FK组成的复合PK组成的关联表:

Hi, we have taken over a project which contains an association table comprised of a composite PK which are also two FK's:

这些表之间的关系是使用流畅的API定义的:

And the relationship between these tables is defined using the fluent API:

然而, ProductFieldOptions 表在代码第一实体数据模型中不存在(即在db上下文中不包含数据库集条目),因此我们无法通过代码访问此实体。

However, the ProductFieldOptions table does not exist in the code first entity data model (i.e. contains no db set entry in the db context) so we have no access to this entity via code.

因此看起来在初始迁移运行后手动输入种子迁移中的CREATE脚本。

It would therefore seem like the CREATE script above in the seed migration was manually entered after the initial migration ran.

所以我们需要知道我们是否有办法访问< strong> ProductFieldOptions  实体?此外,该系统已经存在,该表包含大量数据,因此我们仅限于在数据模型级别可以执行的操作。
非常奇怪,我从来没有见过使用lilke的表,它在db上下文类中包含一个实体。

So we need to know if there is a way in which we can get access to the ProductFieldOptions entity? Also, this system is already live and this table contains alot of data so we are restricted to what we can do at a data model level. Its very strange, I have never seen a table being used lilke this which does contain an entity in the db context class.

任何帮助表示感谢!

推荐答案

嗨DarrenOD,

Hi DarrenOD,

>>所以我们需要知道是否有办法可以访问 ProductFieldOptions  实体?

>>So we need to know if there is a way in which we can get access to the ProductFieldOptions entity?

对于实体框架 多对多,该关系在Fluent API中定义。我们可以通过导航属性访问它们,如下所示:

For entity framework many-to-many, The relationship is defined in Fluent API. we could access them via navigate property, like this:

using (var dbCtx = new SchoolDBEntities())
    {
        /* 1- Get existing data from database */
        var existingStudent = dbCtx.Students.Include("Courses")
                .Where(s => s.StudentName == stud.StudentName).FirstOrDefault<Student>();

        /* 2- Find deleted courses from student's course collection by 
        students' existing courses (existing data from database) minus students' 
        current course list (came from client in disconnected scenario) */
        var deletedCourses = existingStudent.Courses.Except(stud.Courses, 
                cours => cours.CourseId).ToList<Course>();

        /* 3- Find Added courses in student's course collection by students' 
        current course list (came from client in disconnected scenario) minus 
        students' existing courses (existing data from database)  */
        var addedCourses = stud.Courses.Except(existingStudent.Courses, 
                cours => cours.CourseId).ToList<Course>();

        /* 4- Remove deleted courses from students' existing course collection 
        (existing data from database)*/
        deletedCourses.ForEach(c => existingStudent.Courses.Remove(c));
                
        //5- Add new courses
        foreach(Course c in addedCourses)
        {
            /*6- Attach courses because it came from client 
            as detached state in disconnected scenario*/
            if (dbCtx.Entry(c).State == System.Data.EntityState.Detached)
                dbCtx.Courses.Attach(c);

            //7- Add course in existing student's course collection
            existingStudent.Courses.Add(c);
        }

        //8- Save changes which will reflect in StudentCourse table only
        dbCtx.SaveChanges();
    }


 

此外,您还可以通过包含连接表的实体类并映射两个单独的一对多关系来表示多对多关系。像这样:

 

In addition, you could also represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships. like this:

class MyContext : DbContext
{
    public DbSet<Post> Posts { get; set; }
    public DbSet<Tag> Tags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<PostTag>()
            .HasKey(t => new { t.PostId, t.TagId });

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Post)
            .WithMany(p => p.PostTags)
            .HasForeignKey(pt => pt.PostId);

        modelBuilder.Entity<PostTag>()
            .HasOne(pt => pt.Tag)
            .WithMany(t => t.PostTags)
            .HasForeignKey(pt => pt.TagId);
    }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class Tag
{
    public string TagId { get; set; }

    public List<PostTag> PostTags { get; set; }
}

public class PostTag
{
    public int PostId { get; set; }
    public Post Post { get; set; }

    public string TagId { get; set; }
    public Tag Tag { get; set; }
}

有关更多信息,请参阅(请查看多对多阶段):

For more information, please refer to(please check the phase Many-to-many):

https://docs.microsoft.com/en-us/ef/core/建模/关系

祝你好运,

张龙武


这篇关于代码优先于db上下文中没有实体的多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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