首页 > 解决方案 > 如何检查 EntityEntry 是否派生自 BaseEntity在 C# 中

问题描述

BaseEntity<TKey>对所有实体都有一个具有共同审计属性的,

BaseEntity<TKey>

public class BaseEntity<TKey>
{
    public TKey Id { get; protected set; }

    public bool Active { get; protected set; }

    public DateTimeOffset CreatedAt { get; protected set; }

    public string CreatedBy { get; protected set; }

    public DateTimeOffset? ModifiedAt { get; protected set; }

    public string ModifiedBy { get; protected set; }
}

以及具有不同键的派生实体,例如

派生实体:

public class Book : BaseEntity<int>
{
    public string Name { get; set; }
}

public class Author : BaseEntity<Guid>
{
    public string Name { get; set; }
}

public class BookAuthor
{
    public int AuthorId { get; set; }
    public Author Author { get; set; }
    public Guid BookId { get; set; }
    public Book Book { get; set; }
}

我正在尝试在我的 EF Core 添加创建/更新的用户和时间戳详细信息SaveChangesAsync()。但我无法做到这一点。

覆盖SaveChangesAsync()

public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{

    ChangeTracker.DetectChanges();
    var timestamp = DateTimeOffset.Now;
    var user = "User Name";
    var entityEntries = ChangeTracker
                        .Entries()
                        .Where(e => e.Entity is BaseEntity<>
                                    && (e.State.Equals(EntityState.Added) || e.State.Equals(EntityState.Modified))
                                    && !e.Metadata.IsOwned());

    foreach (var entry in entityEntries)
    {
        entry.Property("ModifiedAt").CurrentValue = timestamp;
        entry.Property("ModifiedBy").CurrentValue = user;

        if (entry.State.Equals(EntityState.Added))
        {
            entry.Property("CreatedAt").CurrentValue = timestamp;
            entry.Property("CreatedBy").CurrentValue = user;
            entry.Property("Active").CurrentValue = true;
        }
    }

    return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}

如何签e.Entity is BaseEntity<>入我的LINQ查询?如果我删除条件并运行;然后BookAuthor会抛出异常,因为它们没有审计属性。请协助

标签: c#

解决方案


需要明确的是,基类在您描述的方式中并不“常见”。

如果你有两个派生类

public class Book : BaseEntity<int>
public class Author : BaseEntity<Guid> 

BaseEntity<int>并且BaseEntity<Guid> 实际上是两种不同的类型。两者不共享一个共同的基类,因此除了对象之外,没有共同的类型可以转换为其他类型。如果您希望基类通用,则必须使用单独的方法。例如,使用不采用通用参数并将 TKey Id 作为对象的基类。

或者你有一个像这样的通用基类:

public class BaseEntity
{
    public bool Active { get; protected set; }

    public DateTimeOffset CreatedAt { get; protected set; }

    public string CreatedBy { get; protected set; }

    public DateTimeOffset? ModifiedAt { get; protected set; }

    public string ModifiedBy { get; protected set; }
}

public class BaseEntity<TKey> : BaseEntity
{
    public TKey Id { get; protected set; }
}

然后您可以执行以下操作:

var entityEntries = ChangeTracker
                    .Entries()
                    .Where(e => e.Entity is BaseEntity
                                && (e.State.Equals(EntityState.Added) || 
e.State.Equals(EntityState.Modified))
                                && !e.Metadata.IsOwned());

推荐阅读