簡體   English   中英

如何正確插入多對多關系?

[英]How to insert properly into a many-to-many relationship?

將數據插入多對多關系時,應該插入連接表還是兩個原始表?

我的桌子型號:

public DbSet<User> Users { get; set; }
public DbSet<Group> Groups { get; set; }
public DbSet<GroupMember> GroupMembers { get; set; }

它們之間的關系用Fluent API配置:

builder.Entity<GroupMembers>().HasKey(gm => new { gm.UserId, gm.GroupId });
builder.Entity<GroupMembers>().HasOne(gm => gm.Group).WithMany(group => group.GroupMembers).HasForeignKey(gm => gm.GroupId);
builder.Entity<GroupMembers>().HasOne(gm => gm.User).WithMany(user => user.GroupMembers).HasForeignKey(gm => gm.UserId);
public class Group
{
    [Key]
    public Guid Id { get; set; }
    public string Name { get; set; }

    public List<GroupMember> GroupMembers { get; set; } = new List<GroupMembers>();
}

public class User
{
    [Key]
    public Guid Id { get; set; }
    public string Username { get; set; }

    public List<GroupMembers> GroupMembers { get; set; } = new List<GroupMembers>();
}

public class GroupMembers
{
    [Key]
    public Guid UserId { get; set; }
    public User User { get; set; }

    [Key]
    public Guid GroupId { get; set; }
    public Group Group { get; set; }
}

現在,問題是; 我應該在哪些表/類中插入有關組成員的數據? 是不是這樣:

GroupMembers groupMember = new GroupMembers
{
    Group = group,
    GroupId = group.Id,
    User = user,
    UserId = user.Id
};


user.GroupMembers.Add(groupMember);
group.GroupMembers.Add(groupMember)

_databaseContext.Users.Update(user);
_databaseContext.SaveChanges();;

_databaseContext.Groups.Update(group);
_databaseContext.SaveChanges();

或者像這樣,保持用戶和組不變,僅在連接表中提供有關它們關系的信息:

GroupMembers groupMember = new GroupMembers
{
    Group = group,
    GroupId = group.Id,
    User = user,
    UserId = user.Id
};


_databaseContext.GroupMembers.Add(groupMember);
_databaseContext.SaveChanges();

就實體框架而言,這不是多對多的關系

您在這里擁有的是三種實體類型,它們之間定義了兩個一對多的關系。 您可能知道這樣做是為了表示多對多,但 EF 不知道這一點。

如果我在維護結構的同時隨意更改實體的名稱,您將無法判斷這是否是多對多關系。

簡單的例子:

public class Country {}

public class Company {}

public class Person
{
    public int CountryOfBirthId { get; set; }
    public virtual Country CountryOfBirth { get; set; }

    public int EmployerId { get; set; }
    public virtual Company Employer { get; set; }
}

您最初不會認為Person代表CountryCompany之間的多對多關系,對嗎? 然而,這在結構上與您的示例相同。

從本質上講,您對代碼的處理方式與您處理任何一對多關系的方式應該沒有什么不同。 GroupMembers是一個和其他表一樣的表(數據庫集),EF 希望您將其視為普通實體表。

這里唯一不同的是,因為GroupMember兩個一對多關系,其中它是“多”,因此您必須提供兩個FK(每個相關實體一個)。 但是處理方式與這里只有一對多的關系完全一樣。

換句話說,將您的groupMember添加到表本身:

GroupMembers groupMember = new GroupMembers
{
    // You don't have to fill in the nav props if you don't need them
    GroupId = group.Id,
    UserId = user.Id
};

_databaseContext.GroupMembers.Add(groupMember);
_databaseContext.SaveChanges();

注意:以下僅適用於非核心實體框架,因為EF Core 尚不支持它

如果中間表不是由您管理,那么(非核心)EF 中“真正的”多對多關系的一個示例是:

public class MyContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Group> Groups { get; set; }
}

public class Group
{
    [Key]
    public Guid Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<User> Users { get; set; }
}

public class User
{
    [Key]
    public Guid Id { get; set; }
    public string Username { get; set; }

    public virtual ICollection<Group> Groups { get; set; }
}

在這種情況下,EF 仍然會在數據庫中生成交叉表,但EF 會對您隱藏此表 在這里,您應該通過導航道具工作:

var user = myContext.Users.First();
var group = myContext.Groups.First();

user.Groups.Add(group);

myContext.SaveChanges();

是否使用“真正的”多對多關系或自己管理交叉表取決於您。 當我無法避免時,我傾向於只自己管理交叉表,例如,當我想要交叉表上的其他數據時。

確保數據 id 正確且存在

GroupMembers groupMember = new GroupMembers
{
    GroupId = group.Id,
    UserId = user.Id
};

_databaseContext.GroupMembers.Add(groupMember);
_databaseContext.SaveChanges();

代碼行更少,您必須假設 object 在插入時是完全獨立的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM