我有一个实体基本类别:
public class Entity<TKey>
{
public TKey Id { get; private set; }
private List<INotification> _domainEvents;
public IReadOnlyCollection<INotification> DomainEvents => _domainEvents;
…
}
我的实体可以具有不同类型的ID:Entity
问题是我需要使用ChangeTracker的域实体:
var domainEntities = context.ChangeTracker
.Entries<Entity<TSomeType>>()
.Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any());
在没有通用基类的情况下,我只是放置了“ Entity”并可以工作,但是我有一个通用且不知道TSomeType的可能类型。如何获取条目?
答案 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();