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);
        });
    }
}

这里本想将实体WorkNodeWorkNodeEvent配置为表共享,但系统提示 外键表约束“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();
}

测试结果:

在同一数据库上下文去除同一数据其实例相等
在同一数据库上下文去除同一数据其实例相等

完整代码请见TestEFAbstractEntity1

posted @ 2021-09-23 15:35  $("#阿飞")  阅读(54)  评论(0编辑  收藏  举报