我正在尝试编写一个通用方法,如:
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(???)
中的内容。
有帮助吗?
答案 0 :(得分:3)
虽然您可以尝试使它正常工作,但会发现Entity Framework Core无法解析反射代码,这意味着它将在内存中运行FirstOrDefaultAsync
。因此,如果您有一个包含1000行的表,那么所有这些行将从数据库中提取并在那里进行过滤。有一些解决方案:
使用DbSet.Find方法,看起来它可以完全完成您要实现的目标。例如:
var entity = await _db.Set<TU>().FindAsync(id)
使您的实体实现通用接口,例如:
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);
}
手动构建表达式。这涉及更多的工作,我将不展示如何执行此操作,因为在这种情况下几乎肯定不需要这样做。