在匿名方法中获取匿名对象的值

时间:2018-11-30 14:11:41

标签: c# generics entity-framework-core

我正在尝试编写一个通用方法,如:

protected async Task<ResultModel<TU>> GetEntityByIdAsync<TU, TKey>(TKey id) where TU : class
    {
        try
        {
            var result = await _db.Set<TU>().FirstOrDefaultAsync(x =>
                x.GetType().GetProperty("Id").GetValue(???).ToString() == id.ToString());
            return result.ToResultModel();
        }
        catch (Exception ex)
        {
            _logger.Error($"Error In GetEntityByIdAsync {typeof(TU).Name}. Error: {ex}");
            throw;
        }
    }

但我无法弄清楚应放入GetValue(???)中的内容。 有帮助吗?

1 个答案:

答案 0 :(得分:3)

虽然您可以尝试使它正常工作,但会发现Entity Framework Core无法解析反射代码,这意味着它将在内存中运行FirstOrDefaultAsync。因此,如果您有一个包含1000行的表,那么所有这些行将从数据库中提取并在那里进行过滤。有一些解决方案:

  1. 使用DbSet.Find方法,看起来它可以完全完成您要实现的目标。例如:

    var entity = await _db.Set<TU>().FindAsync(id)
    
  2. 使您的实体实现通用接口,例如:

    public interface IEntity
    {
        int Id { get; }
    }
    

    表示实体的外观应如下所示:

    public class SomeEntity : IEntity
    {
        public int Id { get; set; }
    }
    

    最后,您的方法现在看起来简单得多:

    protected async Task<ResultModel<TU>> GetEntityByIdAsync<TU, TKey>(TKey id)
        where TU : IEntity
    {
        return await _db.Set<TU>.FirstOrDefaultAsync(x => x.Id == id);
    }
    
  3. 手动构建表达式。这涉及更多的工作,我将不展示如何执行此操作,因为在这种情况下几乎肯定不需要这样做。