C# 使用ChangeTacker获取通用条目

C# 使用ChangeTacker获取通用条目,c#,entity-framework-core,C#,Entity Framework Core,我有一个实体基础类别: public class Entity<TKey> { public TKey Id { get; private set; } private List<INotification> _domainEvents; public IReadOnlyCollection<INotification> DomainEvents => _domainEvents; … } 公共类实体 { 公钥Id

我有一个实体基础类别:

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

    private List<INotification> _domainEvents;

    public IReadOnlyCollection<INotification> DomainEvents => _domainEvents;

    …
}
公共类实体
{
公钥Id{get;private set;}
私有列表_domainEvents;
公共IReadOnlyCollection DomainEvents=>\u DomainEvents;
…
}
我的实体可以有不同类型的Id:实体,实体,等等

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

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

如果没有泛型基类,我只放了“Entity”并工作,但是我有一个泛型,我不知道TSomeType的可能类型。如何获取条目?

添加一个公共界面:

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;

    …
}
公共接口的可扩展性
{
IReadOnlyCollection域事件{get;}
}
公共类实体:通用性
{
公钥Id{get;private set;}
私有列表_domainEvents;
公共IReadOnlyCollection DomainEvents=>\u DomainEvents;
…
}
一旦这样做,您就可以通过接口访问DomainEvents,例如

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

添加一个通用接口:

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;

    …
}
公共接口的可扩展性
{
IReadOnlyCollection域事件{get;}
}
公共类实体:通用性
{
公钥Id{get;private set;}
私有列表_domainEvents;
公共IReadOnlyCollection DomainEvents=>\u DomainEvents;
…
}
一旦这样做,您就可以通过接口访问DomainEvents,例如

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

以防万一,你们中的一些人也将AggregateRoot作为一个抽象类,与实体一起使用。我提供了一个解决方案来处理这个问题,但也扩展了通用存储库模式

对于作者最初的问题来说,这可能有些过分,但它也处理身份问题,因为作者可能会在DDD中使用它


公共抽象类实体
{
...
}
公共抽象类实体:其中TId:Identity的实体
{      
...
}

公共接口IAggregateRoot
{
IReadOnlyList DomainEvents{get;}
作废ClearEvents();
}
//注意:此处的“IAggregateRoot”需要位于“实体”和“where TId”之间
公共抽象类AggregateRoot:Entity,IAggregGateRoot,其中TId:Identity
{
私有只读列表_domainEvents=new List();
公共虚拟IReadOnlyList DomainEvents=>\u DomainEvents.AsReadOnly();
受保护的虚拟void AddDomainEvent(IDomainEvent newEvent)
{
_domainEvents.Add(newEvent);
}
公共虚拟void ClearEvents()
{
_domainEvents.Clear();
}
}
公共类OrderId:Identity
{
...
}
公共接口i位置,其中T:AggregateRoot
工业贸易署何处:身分
{
T添加(T实体);
...
}
公共接口IOrderRepository:IRepository
{
...
}
您使用ChangeTracker上的IAggregateRoot


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


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

以防万一,你们中的一些人也将AggregateRoot作为一个抽象类,与实体一起使用。我提供了一个解决方案来处理这个问题,但也扩展了通用存储库模式

对于作者最初的问题来说,这可能有些过分,但它也处理身份问题,因为作者可能会在DDD中使用它


公共抽象类实体
{
...
}
公共抽象类实体:其中TId:Identity的实体
{      
...
}

公共接口IAggregateRoot
{
IReadOnlyList DomainEvents{get;}
作废ClearEvents();
}
//注意:此处的“IAggregateRoot”需要位于“实体”和“where TId”之间
公共抽象类AggregateRoot:Entity,IAggregGateRoot,其中TId:Identity
{
私有只读列表_domainEvents=new List();
公共虚拟IReadOnlyList DomainEvents=>\u DomainEvents.AsReadOnly();
受保护的虚拟void AddDomainEvent(IDomainEvent newEvent)
{
_domainEvents.Add(newEvent);
}
公共虚拟void ClearEvents()
{
_domainEvents.Clear();
}
}
公共类OrderId:Identity
{
...
}
公共接口i位置,其中T:AggregateRoot
工业贸易署何处:身分
{
T添加(T实体);
...
}
公共接口IOrderRepository:IRepository
{
...
}
您使用ChangeTracker上的IAggregateRoot


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


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

我不确定它是否能100%工作,这取决于您的实现,但也许可以尝试添加一个泛型类型,并对该代码所在的方法(或类)进行约束,例如:
void somethod(),其中tenty:Entity
然后在代码中使用该泛型:
var domainenties=context.ChangeTracker.Entries()。其中(x=>x.Entity.DomainEvents!=null&&x.Entity.DomainEvents.Any());
我不确定它是否能100%工作,这取决于您的实现,但可以尝试添加一个泛型类型,并对该代码所在的方法(或类)进行约束,例如:
void somethod(),其中tenty:Entity
,然后在代码中使用此泛型类型:<