Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使此查询在LINQ to实体中工作?_C#_Linq_Linq To Entities_Expression Trees - Fatal编程技术网

C# 如何使此查询在LINQ to实体中工作?

C# 如何使此查询在LINQ to实体中工作?,c#,linq,linq-to-entities,expression-trees,C#,Linq,Linq To Entities,Expression Trees,我必须输入以下代码: private static bool doescalvalueexist(IQueryable dataToSearchIn、string colName、string colValue) { int noOfClients=1; 类型=类型(T); if(colValue!=“”&&colName!=“”) { var property=type.GetProperty(colName); var参数=表达式参数(类型为“p”); var propertyAccess=

我必须输入以下代码:

private static bool doescalvalueexist(IQueryable dataToSearchIn、string colName、string colValue)
{
int noOfClients=1;
类型=类型(T);
if(colValue!=“”&&colName!=“”)
{
var property=type.GetProperty(colName);
var参数=表达式参数(类型为“p”);
var propertyAccess=Expression.MakeMemberAccess(参数,属性);
Expression left=Expression.Call(propertyAccess,typeof(object).GetMethod(“ToString”,System.Type.EmptyTypes));
left=Expression.Call(left,typeof(string).GetMethod(“ToLower”,System.Type.EmptyTypes));
Expression right=Expression.Constant(colValue.ToLower(),typeof(string));
MethodInfo method=typeof(string).GetMethod(“等于”,新[]{typeof(string)});
Expression searchExpression=Expression.Call(左、方法、右);
MethodCallExpression,其中CallExpression=Expression.Call(
类型(可查询),
“哪里”,
新类型[]{Type},
dataToSearchIn.Expression,
Lambda(searchExpression,新参数Expression[]{parameter}));
var searchedData=dataToSearchIn.Provider.CreateQuery(whereCallExpression);
noOfClients=searchedData.Cast().Count();
if(noOfClients==0)
返回false;
其他的
返回true;
}
返回true;
}
它与LINQ to SQL一起工作,但与LINQ to Entities一起工作时,我得到错误:

LINQ to Entities无法识别方法“System.String ToString()”方法,并且无法将此方法转换为存储表达式


Linq to Entities不支持.ToString()方法。我也不确定对非字符串类型使用字符串比较是否是一个好主意。但并不是所有的东西都丢了。我提出了以下解决方案:

public partial class MyEntity
{
    public int ID { get; set; }
    public int Type { get; set; }
    public string X { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<MyEntity> Entities { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());

        using (var ctx = new MyContext())
        {
            if (!ctx.Entities.Any())
            {
                ctx.Entities.Add(new MyEntity() { ID = 1, Type = 2, X = "ABC" });
                ctx.SaveChanges();
            }

            Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.X, "aBc"));
            Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.X, "aBcD"));
            Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.Type, 2));
            Console.WriteLine(DoesColValueExist(ctx.Entities, e => e.Type, 5));

        }
    }

    private static bool DoesColValueExist<TEntity, TProperty>(IQueryable<TEntity> dataToSearchIn, Expression<Func<TEntity, TProperty>> property, TProperty colValue)
    {

        var memberExpression = property.Body as MemberExpression;
        if (memberExpression == null || !(memberExpression.Member is PropertyInfo))
        {
            throw new ArgumentException("Property expected", "property");
        }

        Expression left = property.Body;
        Expression right = Expression.Constant(colValue, typeof(TProperty));
        if (typeof(TProperty) == typeof(string))
        {
            MethodInfo toLower = typeof(string).GetMethod("ToLower", new Type[0]);
            left = Expression.Call(left, toLower);
            right = Expression.Call(right, toLower);
        }

        Expression searchExpression = Expression.Equal(left, right);
        var lambda = Expression.Lambda<Func<TEntity, bool>>(Expression.Equal(left, right), new ParameterExpression[] { property.Parameters.Single() });

        return dataToSearchIn.Where(lambda).Any();                
    }
}
公共部分类MyEntity
{
公共int ID{get;set;}
公共int类型{get;set;}
公共字符串X{get;set;}
}
公共类MyContext:DbContext
{
公共数据库集实体{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
SetInitializer(新的DropCreateDatabaseIfModelChanges());
使用(var ctx=new MyContext())
{
如果(!ctx.Entities.Any())
{
添加(new MyEntity(){ID=1,Type=2,X=“ABC”});
ctx.SaveChanges();
}
WriteLine(doesclvalueexist(ctx.Entities,e=>e.X,“aBc”);
WriteLine(doesclvalueexist(ctx.Entities,e=>e.X,“aBcD”);
WriteLine(doesclvalueexist(ctx.Entities,e=>e.Type,2));
WriteLine(doesclvalueexist(ctx.Entities,e=>e.Type,5));
}
}
私有静态bool doescalvalueexist(IQueryable dataToSearchIn、Expression属性、TProperty colValue)
{
var memberExpression=property.Body作为memberExpression;
if(memberExpression==null | |!(memberExpression.Member为PropertyInfo))
{
抛出新ArgumentException(“预期属性”、“属性”);
}
表达式left=property.Body;
表达式右=表达式常数(colValue,typeof(TProperty));
if(typeof(TProperty)=typeof(string))
{
MethodInfo toLower=typeof(string).GetMethod(“toLower”,新类型[0]);
left=表达式.Call(left,toLower);
right=表达式.Call(right,toLower);
}
表达式searchExpression=Expression.Equal(左、右);
var lambda=Expression.lambda(Expression.Equal(左、右),新参数Expression[]{property.Parameters.Single()});
将数据返回到earchin.Where(lambda.Any();
}
}
它的优点在于它比基于字符串的解决方案更为类型安全——参数的值必须与属性的值相同。属性反过来必须是作为第一个参数传递的IQueryable'1的泛型类型的实体的成员。另一个有用的东西是,当您开始为第二个参数键入lambda表达式时,针对此方法进行编码时,intellisense将显示实体的成员。在方法本身中,当我对属性值和请求的值调用.ToLower()时,我为字符串类型添加了一个异常,以使比较不区分大小写。对于非字符串类型,将“按原样”比较值,即不进行任何修改。 上面的示例已完成-您可以将其复制并粘贴到控制台应用程序项目(但需要引用EntityFramework.dll)。 希望这有帮助

试试这个:

private static bool DoesColValueExist<T>(IQueryable dataToSearchIn, string colName, string colValue)
{
    int noOfClients = 1;
    Type type = typeof(T);
    if (colValue != "" && colName != "")
    {
        var property = type.GetProperty(colName);
        var parameter = Expression.Parameter(type, "p");
        var propertyAccess = Expression.MakeMemberAccess(parameter, property);
        Expression left = property.PropertyType == typeof(string) ? propertyAccess : Expression.Call(propertyAccess, typeof(object).GetMethod("ToString", System.Type.EmptyTypes));
        left = Expression.Call(left, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
        Expression right = Expression.Constant(colValue.ToLower(), typeof(string));
        MethodInfo method = typeof(string).GetMethod("Equals", new[] { typeof(string) });
        Expression searchExpression = Expression.Call(left, method, right);


        MethodCallExpression whereCallExpression = Expression.Call(
            typeof(Queryable),
            "Where",
            new Type[] { type },
            dataToSearchIn.Expression,
            Expression.Lambda<Func<T, bool>>(searchExpression, new ParameterExpression[] { parameter }));
        var searchedData = dataToSearchIn.Provider.CreateQuery(whereCallExpression);
        noOfClients = searchedData.Cast<T>().Count();

        if (noOfClients == 0)
            return false;
        else
            return true;
    }
    return true;
}
private static bool doescalvalueexist(IQueryable dataToSearchIn、string colName、string colValue)
{
int noOfClients=1;
类型=类型(T);
if(colValue!=“”&&colName!=“”)
{
var property=type.GetProperty(colName);
var参数=表达式参数(类型为“p”);
var propertyAccess=Expression.MakeMemberAccess(参数,属性);
表达式left=property.PropertyType==typeof(string)?propertyAccess:Expression.Call(propertyAccess,typeof(object).GetMethod(“ToString”,System.Type.EmptyTypes));
left=Expression.Call(left,typeof(string).GetMethod(“ToLower”,System.Type.EmptyTypes));
Expression right=Expression.Constant(colValue.ToLower(),typeof(string));
MethodInfo method=typeof(string).GetMethod(“等于”,新[]{typeof(string)});
Expression searchExpression=Expression.Call(左、方法、右);
MethodCallExpression,其中CallExpression=Expression.Call(
类型(可查询),
“哪里”,
新类型[]{Type},
dataToSearchIn.Expression,
Lambda(searchExpression,新参数Expression[]{parameter}));
var-se