.net core 通过EF中的ValueTask加载通用异步数据

.net core 通过EF中的ValueTask加载通用异步数据,.net-core,entity-framework-core,.net Core,Entity Framework Core,我在实体框架中为我的所有实体都有一个基类,它提供一般属性(例如id、更改/创建日期) 现在我需要检查一些实体(它们的数据库表)是否有更改,为此,我编写了一个类,定期将所有可用ID及其更改日期(从基本实体)与以前加载的ID/日期进行比较 这很快就变得复杂了,因为我对泛型和处理泛型不太深入。我使用以下字典存储跟踪类型和相关数据/信息: private readonly Dictionary<Type, ObservingEntity> _observingEntities; 这确实有效

我在实体框架中为我的所有实体都有一个基类,它提供一般属性(例如id、更改/创建日期)

现在我需要检查一些实体(它们的数据库表)是否有更改,为此,我编写了一个类,定期将所有可用ID及其更改日期(从基本实体)与以前加载的ID/日期进行比较

这很快就变得复杂了,因为我对泛型和处理泛型不太深入。我使用以下字典存储跟踪类型和相关数据/信息:

private readonly Dictionary<Type, ObservingEntity> _observingEntities;
这确实有效——但我认为它过于复杂,不喜欢使用
Task
vs
ValueTask
Task
可以毫无问题地转换为
Task
,但由于
ValueTask
是一个结构,因此似乎不可能实现相同的转换(将
ValueTask
转换为
ValueTask
)。我对此感兴趣,因为我希望避免额外的任务分配

因此,我的问题是:

  • 在我的存储库上执行
    GetAll
    是否比使用键入的
    MethodInfo
    引用和
    wait
    使用
    dynamic
    cast(访问结果)更优雅
  • 如何使用
    ValueTask
    而不是
    Task
    来避免分配

  • 我希望避免反射和性能问题代码,以建立接近最佳实践解决方案的东西。

    Task
    更改为
    ValueTak
    不会给您带来很大的好处,因为您会将完整的表加载到内存中。我认为最好在这里解释一下为什么会出现这种方法。避免额外的开销是“很好的”,但您是对的,在实际使用中,这很可能会带来无法衡量的好处。将
    Task
    更改为
    ValueTak
    不会给您带来很大的好处,因为您会将完整的表加载到内存中。我认为最好在这里解释一下为什么会出现这种方法。避免额外的开销是很好的,但你是对的,在实际使用中,这很可能会带来无法衡量的好处。
    private readonly Dictionary<Type, ObservingEntity> _observingEntities;
    
    public class ObservingEntity
    {
        public Type EntityType { get; set; }
        
        public HashSet<Action<Dictionary<Type, BaseEntity[]>>> Callbacks { get; set; }
        
        public ImmutableHashSet<(int, DateTime?)> LatestDataMeta { get; set; }
        
        public MethodInfo RepositoryGetterReference { get; set; }
    
        public ObservingEntity(Type entityType)
        {
            EntityType = entityType;
            Callbacks = new HashSet<Action<Dictionary<Type, BaseEntity[]>>>();
            var getter = typeof(IReadRepository).GetMethod("GetAll");
            RepositoryGetterReference = getter.MakeGenericMethod(entityType);
        }
    }
    
    public async Task<T[]> GetAll<T>() where T : BaseEntity
    {
        return await _context.Set<T>()
            .ToArrayAsync();
    }
    
    foreach (var entityEntry in _observingEntities)
    {
        var task = (Task)entityEntry.Value.RepositoryGetterReference.Invoke(_repository, null);
        await task;
        var currentData = (BaseEntity[])((dynamic)task).Result;
    }