使用ChangeTacker获取通用条目

时间:2018-10-06 09:13:51

标签: c# entity-framework-core

我有一个实体基本类别:

public class Entity<TKey>
{
    public TKey Id { get; private set; }

    private List<INotification> _domainEvents;

    public IReadOnlyCollection<INotification> DomainEvents => _domainEvents;

    …
}

我的实体可以具有不同类型的ID:Entity ,Entity 等。

问题是我需要使用ChangeTracker的域实体:

var domainEntities = context.ChangeTracker
    .Entries<Entity<TSomeType>>()
    .Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any());

在没有通用基类的情况下,我只是放置了“ Entity”并可以工作,但是我有一个通用且不知道TSomeType的可能类型。如何获取条目?

2 个答案:

答案 0 :(得分:1)

添加公共界面:

public interface IEntity
{
    IReadOnlyCollection<INotification> DomainEvents { get; }
}

public class Entity<TKey> : IEntity
{
    public TKey Id { get; private set; }

    private List<INotification> _domainEvents;

    public IReadOnlyCollection<INotification> DomainEvents => _domainEvents;

    …
}

完成此操作后,您可以通过界面访问DomainEvents,例如

var domainEntities = context.ChangeTracker
    .Entries<Entity<TSomeType>>()
    .Cast<IEntity>()
    .Where(x => x.DomainEvents != null && x.DomainEvents.Any());

答案 1 :(得分:0)

以防万一,有些人还将AggregateRoot用作与Entity紧密结合的抽象类。我提供了一个解决此问题的解决方案,但也扩展了通用存储库模式。

这对于作者最初提出的问题可能是一个过分的矫正,但由于作者可能会在DDD中使用它,因此它也可以处理身份。


    public abstract class Entity
    {
        ...
    }

    public abstract class Entity<TId> : Entity where TId : Identity
    {      
        ...
    }

    public interface IAggregateRoot
    {
        IReadOnlyList<IDomainEvent> DomainEvents { get; }
        void ClearEvents();
    }

    // Note: Here the 'IAggregateRoot' needs to be inbetween 'Entity<TId>' & 'where TId'
    public abstract class AggregateRoot<TId> : Entity<TId>, IAggregateRoot where TId : Identity
    {
        private readonly List<IDomainEvent> _domainEvents = new List<IDomainEvent>();
        public virtual IReadOnlyList<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();

        protected virtual void AddDomainEvent(IDomainEvent newEvent)
        {
            _domainEvents.Add(newEvent);
        }

        public virtual void ClearEvents()
        {
            _domainEvents.Clear();
        }
    }

    public class OrderId : Identity
    {
         ...
    }

    public interface IRepository<T, TId> where T : AggregateRoot<TId>
                                         where TId: Identity
    {
        T Add(T entity);
        ...
    }

    public interface IOrderRepository : IRepository<Order, OrderId>
    {
       ...
    }

然后在ChangeTracker上使用IAggregateRoot


var domainEntities = ChangeTracker.Entries<IAggregateRoot>()
               .Select(x => x.Entity)
               .Where(x => x.DomainEvents.Any())
               .ToList();