在EntityFramework中使用'where'声明
本文关键字:where 声明 EntityFramework | 更新日期: 2023-09-27 17:55:04
我需要创建一个通用方法来获取与另一个实体相关的一些数据。
这是我的代码目前的样子:
public static void InvalidateData<TEntity>(string foreignKey, int valueFK)
{
try
{
var key = typeof(TEntity).Name;
var adapter = (IObjectContextAdapter)EntityModelDataProvider.Database;
var objectContext = adapter.ObjectContext;
var container = objectContext.MetadataWorkspace.GetEntityContainer(
objectContext.DefaultContainerName, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace);
var name = container.BaseEntitySets.Where((s) => s.ElementType.Name.Equals(key)).FirstOrDefault().Name;
string sqlQuery = String.Format(@"SELECT VALUE entity FROM [VW_{0}] WHERE entity.{1} = @foreignkey", name, foreignKey);
var query = objectContext.CreateQuery<TEntity>(sqlQuery, new ObjectParameter("foreignkey", valueFK));
var tmpResult = query.ToList();
}
catch (Exception)
{
throw;
}
}
和错误:
生成的查询:的实体。在当前作用域或上下文中无法解析Average_FK'。确保所有引用的变量都在作用域中,加载了所需的模式,并且正确引用了名称空间。近成员访问表达式,第1行,第58列。
SELECT VALUE entity FROM [VW_Average_Client] WHERE entity.Average_FK = @foreignkey
我检查了实体的属性,我确实有一个名为"Average_FK"。
知道如何实现我的目标吗?
我正试图实现一个通用的地方,像这样:
Expression<Func<TEntity, bool>> customFilter = entity => ComparePropertyValue<TEntity>(entity, foreignKey, valueFK);
var query = objectContext.CreateQuery<TEntity>("[" + name + "]").Where(customFilter);
…
private static bool ComparePropertyValue<TEntity>(TEntity entity, string property, object value)
{
try
{
PropertyInfo propertyInfo = typeof(TEntity).GetProperty(property);
return propertyInfo.GetValue(entity) == value;
}
catch (Exception)
{
throw;
}
}
还有这个例外:
LINQ to Entities不识别方法'Boolean ComparePropertyValue[VW_Average_Client](XXX.EntityModel.)VW_Average_Client、系统。字符串,System.Object)'方法,并且该方法不能转换为存储表达式。
我终于找到了解决办法。
(如果有人想发布一个更好/更干净的答案,我会设置你的作为有效的)
public static void InvalidateDataGeneric<TEntity>(string foreignKey, int valueFK)
{
try
{
var key = typeof(TEntity).Name;
var adapter = (IObjectContextAdapter)EntityModelDataProvider.Database;
var objectContext = adapter.ObjectContext;
var container = objectContext.MetadataWorkspace.GetEntityContainer(
objectContext.DefaultContainerName, System.Data.Entity.Core.Metadata.Edm.DataSpace.CSpace);
var name = container.BaseEntitySets.Where((s) => s.ElementType.Name.Equals(key)).FirstOrDefault().Name;
Func<TEntity, bool> filter = algo => ComparePropertyValue<TEntity>(algo, foreignKey, valueFK);
var query = objectContext.CreateQuery<TEntity>("[" + name + "]").Where(filter);
foreach (var element in query)
{
// whatever
}
objectContext.SaveChanges();
}
catch (Exception)
{
throw;
}
}
private static bool ComparePropertyValue<TEntity>(TEntity entity, string property, object value)
{
try
{
PropertyInfo propertyInfo = typeof(TEntity).GetProperty(property);
return propertyInfo.GetValue(entity).Equals(value);
}
catch (Exception)
{
throw;
}
}
使用entity
的地方是错误的,它应该是:
string sqlQuery = String.Format(@"SELECT VALUE FROM [VW_{0}] entity WHERE entity.{1} = @foreignkey", name, foreignKey);
甚至省略entity
:
string sqlQuery = String.Format(@"SELECT VALUE FROM [VW_{0}] WHERE {1} = @foreignkey", name, foreignKey);
(注意-我同意上面的评论,由于几个原因,这不是一个推荐的方法;还有更好的&更清洁的解决方案达到同样的效果。但这并不能回答问题…)