C# 在匿名方法中获取匿名对象的值
我正在尝试编写一个通用方法,如:C# 在匿名方法中获取匿名对象的值,c#,generics,entity-framework-core,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 =>
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;
}
}
受保护的异步任务GetEntityByIdAsync(TKey id),其中TU:class
{
尝试
{
var result=await\u db.Set().FirstOrDefaultAsync(x=>
x、 GetType().GetProperty(“Id”).GetValue(???).ToString()==Id.ToString();
返回result.ToResultModel();
}
捕获(例外情况除外)
{
_logger.Error($”GetEntityByIdAsync{typeof(TU.Name}中的错误。错误:{ex}”);
投掷;
}
}
但是我不知道应该在GetValue(???)
中输入什么。
有什么帮助吗?虽然您可以让它在您尝试执行的过程中正常工作,但您会发现Entity Framework Core无法解析反射代码,这意味着它将在内存中运行
FirstOrDefaultAsync
。因此,如果您有一个包含1000行的表,那么所有这些行都将从数据库中提取并在那里进行过滤。有几种解决方案:
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);
}
受保护的异步任务GetEntityByIdAsync(TKey id)
屠:什么地方
{
返回wait _db.Set.FirstOrDefaultAsync(x=>x.Id==Id);
}
虽然您可以让它在您尝试的时候工作,但您会发现Entity Framework Core无法解析反射代码,这意味着它将在内存中运行
FirstOrDefaultAsync
。因此,如果您有一个包含1000行的表,那么所有这些行都将从数据库中提取并在那里进行过滤。有几种解决方案:
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);
}
受保护的异步任务GetEntityByIdAsync(TKey id)
屠:什么地方
{
返回wait _db.Set.FirstOrDefaultAsync(x=>x.Id==Id);
}
看起来您正在尝试编写自己版本的
Find
方法,该方法已经为您实现了这一点。特别是因为您正在执行的操作无法使用实体FramWork。GetValue
需要您想要获取其属性值的实例。因此,您可能需要GetValue(x)
。要获得匿名,请实现anonycat…;)@HimBromBeere请不要建议这样的实体框架查询。执行此操作将强制EF将整个表加载到内存中。DavidG所说的是,通过\u db.Set().Find(id)
(或FindAsync
)可以实现同样的效果。换句话说,XY问题。即使你解决了具体的问题,效率也会非常低。看起来你正在尝试编写自己版本的Find
方法,该方法已经为你完成了这项工作。特别是因为您正在执行的操作无法使用实体FramWork。GetValue
需要您想要获取其属性值的实例。因此,您可能需要GetValue(x)
。要获得匿名,请实现anonycat…;)@HimBromBeere请不要建议这样的实体框架查询。执行此操作将强制EF将整个表加载到内存中。DavidG所说的是,通过\u db.Set().Find(id)
(或FindAsync
)可以实现同样的效果。换句话说,XY问题。即使你解决了具体的问题,它也会非常低效。”这意味着它将在内存中运行FirstOrDefaultAsync“不,它只会抛出一个异常。您可以显式地将数据加载到内存中,以防止EF尝试运行它(但您显然不应该这样做)。@Servy恐怕不是真的。这是EF-Core,这意味着它无法默默地转换表达式并在本地进行计算。它会弹出一条要调试的警告消息,但是如果您不注意,像表达式这样的东西将无法翻译并将被计算locally@Servy附带说明,当遇到这些问题时,可以使用and命令EF Core抛出。“这意味着它将在内存中运行FirstOrDefaultAsync”不,它只会抛出一个异常。您可以显式地将数据加载到内存中,以防止EF尝试运行它(但您显然不应该这样做)。@Servy恐怕不是真的。这是EF-Core,这意味着它无法默默地转换表达式并在本地进行计算。它会弹出一条要调试的警告消息,但是如果您不注意,像表达式这样的东西将无法翻译并将被计算locally@Servy旁注,当遇到这些问题时,可以使用and命令EF Core抛出。