gpt4 book ai didi

entity-framework - EF5 和循环或多个级联路径,外键

转载 作者:行者123 更新时间:2023-12-04 05:03:33 25 4
gpt4 key购买 nike

我遇到了一个奇怪的问题,我已经知道为什么会发生这种异常,以及如何通过在其中一个属性中将 WillCascadeOnDelete 禁用为 False 来解决它。

但我的问题似乎是其他类型的,
这是我的代码:

成员(member):

 public class Memeber
{
public int MemberID { get; set; }
public virtual ICollection<Message> SentMessages { get; set; }
public virtual ICollection<Message> RecievedMessages { get; set; }
}

public class Message
{
public long MessageID { get; set; }
public int SenderMemberId{ get; set; }
public virtual ICollection<Member> RecipientsMembers { get; set; }
[ForeignKey("SenderMemberId")]
public virtual Member SenderMember { get; set; }
}

这是映射:
在消息配置中:
    this.HasRequired(c => c.SenderMember)
.WithMany(c => c.SentMessages)
.HasForeignKey(c => c.SenderMemberId)
.WillCascadeOnDelete(false);

在 MemberConfiguration 中:
 this.HasMany(c => c.RecievedMessages)
.WithMany(c => c.RecipientsMembers)

.Map(cm =>
{
cm.ToTable("MessageJoinMemeber");
cm.MapLeftKey("MessageId");
cm.MapRightKey("MemberId");

});

如您所见,消息的发件人具有外键 SenderID,一对多双向。
成员有 2 个消息列表,一个是接收者,一个是发送者。
我试图在这些关系之一中禁用级联删除(第一个)
但我仍然从 SQL 引擎中得到同样的问题。
我还尝试从消息部分而不是从成员部分定义关系
与:
        this.HasMany(c => c.RecipientsMembers)
.WithMany(c=> c.RecievedMessages)
.Map ( cm =>
{
cm.ToTable("MessageJoinMemeber");
cm.MapLeftKey("MessageId");
cm.MapRightKey("MemberId");

});

但我总是收到这个错误:
 System.Data.SqlClient.SqlException was unhandled by user code
HResult=-2146232060
Message=Introducing FOREIGN KEY constraint 'FK_dbo.MessageJoinMemeber_dbo.Messages_MemberId' on table 'MessageJoinMemeber' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.
Source=.Net SqlClient Data Provider
ErrorCode=-2146232060
Class=16
LineNumber=1
Number=1785
Procedure=""
Server=KINGPC
State=0
StackTrace:
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)

最佳答案

这应该可以正常工作(与您所拥有的 相同 )

public class Member
{
public int MemberID { get; set; }
public string Name { get; set; }
public virtual ICollection<Message> SentMessages { get; set; }
public virtual ICollection<Message> RecievedMessages { get; set; }
}
public class Message
{
public long MessageID { get; set; }
public int SenderMemberId { get; set; }
public virtual ICollection<Member> RecipientsMembers { get; set; }
[ForeignKey("SenderMemberId")]
public virtual Member SenderMember { get; set; }
}
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Message>()
.HasRequired(c => c.SenderMember)
.WithMany(c => c.SentMessages)
.HasForeignKey(c => c.SenderMemberId)
.WillCascadeOnDelete(false);

modelBuilder.Entity<Member>()
.HasMany(c => c.RecievedMessages)
.WithMany(c => c.RecipientsMembers)
.Map(cm =>
{
cm.ToTable("MessageJoinMemeber");
cm.MapLeftKey("MessageId");
cm.MapRightKey("MemberId");

});
...
var member = new Member { Name = "sender1" };
db.Messages.Add(new Message
{
SenderMember = new Member { Name = "sender1" },
RecipientsMembers = new List<Member>
{
new Member { Name = "receiver1" },
new Member { Name = "receiver2" },
new Member { Name = "receiver3" },
}
});
db.SaveChanges();

...但如果您仍然有问题,您可以手动制作连接表...
// public virtual ICollection<Message> RecievedMessages { get; set; }
public virtual ICollection<MessageJoinMember> Recieved { get; set; }
...
// public virtual ICollection<Member> RecipientsMembers { get; set; }
public virtual ICollection<MessageJoinMember> Recipients { get; set; }
...
public class MessageJoinMember
{
public long MessageID { get; set; }
public Message Message { get; set; }
public int MemberID { get; set; }
public Member Member { get; set; }
}
...
modelBuilder.Entity<Message>()
.HasRequired(c => c.SenderMember)
.WithMany(c => c.SentMessages)
.HasForeignKey(c => c.SenderMemberId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<MessageJoinMember>()
.HasKey(x => new { x.MessageID, x.MemberID });
modelBuilder.Entity<MessageJoinMember>()
.HasRequired(x => x.Message)
.WithMany(x => x.Recipients)
.HasForeignKey(x => x.MessageID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<MessageJoinMember>()
.HasRequired(x => x.Member)
.WithMany(x => x.Recieved)
.HasForeignKey(x => x.MemberID)
.WillCascadeOnDelete(false);
// remove the implicit many-to-many here
...
var message = new Message { SenderMember = new Member { Name = "sender1" }, };
db.MessageJoinMembers.Add(new MessageJoinMember { Message = message, Member = new Member { Name = "receiver1" } });
db.MessageJoinMembers.Add(new MessageJoinMember { Message = message, Member = new Member { Name = "receiver2" } });
db.MessageJoinMembers.Add(new MessageJoinMember { Message = message, Member = new Member { Name = "receiver3" } });
db.Messages.Add(message);
db.SaveChanges();

关于entity-framework - EF5 和循环或多个级联路径,外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15812227/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com