EntityFramework同一数据库上下文实体多次取出的数据实体相等.md
EntityFramework同一数据库上下文实体多次取出的数据实体相等
代码如下
工作节点基类
public abstract class WorkNode
{
public event Action<WorkNode> OnEndApproval;
public event Action<WorkNode> OnEndReject;
public Guid Id { get; set; }
public string Name { get; set; }
public virtual WorkNode NextNode { get; set; }
public StringBuilder Message { get; } = new StringBuilder();
protected WorkNode() { }
public void Approval()
{
Message.AppendLine("开始审批");
OnEndApproval?.Invoke(this);
}
public void Reject()
{
Message.AppendLine("开始拒绝");
OnEndReject?.Invoke(this);
}
}
简单工作节点,继承工作节点基类
public class SimpleWorkNode : WorkNode
{
public string ApprovalUser { get; set; }
}
工作节点事件类,引用工作节点基类
public class WorkNodeEvent
{
public Guid Id { get; set; }
public string OtherMessage { get; set; }
public virtual WorkNode WorkNode {get;set;}
public void InitEvent()
{
WorkNode.OnEndApproval += WorkNode_OnEndApproval;
WorkNode.OnEndReject += WorkNode_OnEndReject;
}
private void WorkNode_OnEndReject(WorkNode obj)
{
OtherMessage = "Reject";
obj.Message.AppendLine("OnEndReject 事件输出:拒绝结束");
}
private void WorkNode_OnEndApproval(WorkNode obj)
{
OtherMessage = "Approval";
obj.Message.AppendLine("OnEndApproval 事件输出:批准结束");
}
}
数据库上下文
public class Repository : DbContext
{
public Repository(DbContextOptions<Repository> options):base(options)
{
Console.WriteLine("初始化资源库");
}
protected DbSet<WorkNode> WorkNodes { get; set; }
public DbSet<SimpleWorkNode> SimpleWorkNodes { get; set; }
public DbSet<WorkNodeEvent> WorkNodeEvents { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<WorkNode>(p =>
{
p.HasKey(p => p.Id);
});
modelBuilder.Entity<WorkNodeEvent>(p => {
p.HasKey(p => p.Id);
});
}
}
这里本想将实体
WorkNode
和WorkNodeEvent
配置为表共享,但系统提示 外键表约束“FK_WorkNodes_WorkNodes_NextNodeId”与表表"dbo.WorkNodes"的 'Id'列冲突,于是就分两个表存储数据了
测试代码
public async Task AddDataAsync()
{
await LogTitleAsync("添加数据");
var sn1 = new SimpleWorkNode
{
Id = Guid.NewGuid(),
ApprovalUser = "admin1",
Name = "简单节点1",
};
var wnEvent = new WorkNodeEvent {
Id = Guid.NewGuid(),
OtherMessage ="testEvent",
WorkNode=sn1,
};
repository.WorkNodeEvents.Add(wnEvent);
repository.SaveChanges();
await LogTitleAsync("数据添加完成");
}
public async Task ApprovalAsync()
{
await LogTitleAsync("开始审批");
var sn1 = repository.SimpleWorkNodes.FirstOrDefault(p => p.Name.Equals("简单节点1"));
var workEvent = repository.WorkNodeEvents.FirstOrDefault(p => p.WorkNode.Id.Equals(sn1.Id));
workEvent?.InitEvent();
sn1.Approval();
await LogContentAsync($"sn1.Equals(workEvent.WorkNode):{sn1.Equals(workEvent.WorkNode)}");
await LogContentAsync(sn1.Message.ToString());
await LogContentAsync($"OtherMessage:{workEvent.OtherMessage}");
await LogTitleAsync("审批完成");
repository.SaveChanges();
}
测试结果:
![在同一数据库上下文去除同一数据其实例相等 在同一数据库上下文去除同一数据其实例相等](Images%5C%E5%9C%A8%E5%90%8C%E4%B8%80%E6%95%B0%E6%8D%AE%E5%BA%93%E4%B8%8A%E4%B8%8B%E6%96%87%E5%8E%BB%E9%99%A4%E5%90%8C%E4%B8%80%E6%95%B0%E6%8D%AE%E5%85%B6%E5%AE%9E%E4%BE%8B%E7%9B%B8%E7%AD%89.png)
在同一数据库上下文去除同一数据其实例相等
完整代码请见TestEFAbstractEntity1