在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)'方法,并且该方法不能转换为存储表达式。

在EntityFramework中使用'where'声明

我终于找到了解决办法。

(如果有人想发布一个更好/更干净的答案,我会设置你的作为有效的)

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);

(注意-我同意上面的评论,由于几个原因,这不是一个推荐的方法;还有更好的&更清洁的解决方案达到同样的效果。但这并不能回答问题…)