如何解决Entity Framework Core - 一对多,但父级也有单个子级的导航属性?
我目前在实体“对话”和“消息”之间建立了一对多的关系,其中一个对话可以包含多条消息。
这很好用:
public class Conversation
{
public long ID { get; set; }
}
public class Message : IEntity
{
public virtual Conversation Conversation { get; set; }
public long ConversationID { get; set; }
public long ID { get; set; }
}
但是,我正在尝试向名为“LastMessage”的“Conversation”类添加导航属性,该类将跟踪创建的最后一条消息记录:
public class Conversation
{
public long ID { get; set; }
public virtual Message LastMessage { get; set; }
public long LastMessageID { get; set; }
}
system.invalidOperationException:子/依赖方无法 确定之间的一对一关系 “Conversation.LastMessage”和“Message.Conversation”。
如何维护“对话”和“消息”之间的一对多关系,但还要在“对话”类中添加导航属性以导航到单个“消息”记录?
解决方法
如果对话可以有多个消息,则称为一对多关系。 您必须修复表格:
public class Conversation
{
[Key]
public long ID { get; set; }
[InverseProperty(nameof(Message.Conversation))]
public virtual ICollection<Message> Messages { get; set; }
}
public class Message
{
[Key]
public long ID { get; set; }
public long ConversationID { get; set; }
[ForeignKey(nameof(ConversionId))]
[InverseProperty("Messages")]
public virtual Conversation Conversation { get; set; }
}
,
在尝试了各种数据注释和 Fluent API 废话之后,我能想到的最简洁的解决方案非常简单,两者都不需要。它只需要向 Conversation 类添加一个“私有”构造函数(如果您使用的是延迟加载,则为“受保护”构造函数),您的“DbContext”对象被注入到该类中。只需将您的“对话”和“消息”类设置为正常的一对多关系,并且现在可以从“对话”实体中获得数据库上下文,您可以让“最后一条消息”简单地从数据库返回一个查询使用 Find() 方法。 Find() 方法也使用了缓存,因此如果多次调用 getter,它只会访问一次数据库。
这是关于此能力的文档:https://docs.microsoft.com/en-us/ef/core/modeling/constructors#injecting-services
注意:“LastMessage”属性是只读的。要修改它,请设置“LastMessageID”属性。
class Conversation
{
public Conversation() { }
private MyDbContext Context { get; set; }
// make the following constructor 'protected' if you're using Lazy Loading
// if not,make it 'private'
protected Conversation(MyDbContext Context) { this.Context = Context; }
public int ID { get; set; }
public int LastMessageID { get; set; }
public Message LastMessage { get { return Context.Messages.Find(LastMessageID); } }
}
class Message
{
public int ID { get; set; }
public int ConversationID { get; set; }
public virtual Conversation Conversation { get; set; }
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。