繁体   English   中英

表达式lambda动态参数

[英]Expression lambda Dynamic Parameter

在我当前的项目中,存储库使用EntityFramework,其中许多表为News。 因此,每次我们都有一个新的输入功能,我们创建相关的数据库,生成edmx,并在存储库中创建一个新方法。 示例:db.News.Where(c => c.Name =='myNews'); db.Articles.Where(c => c.ArticleName =='myArticle');

我寻找一种避免每次编写都非常相似的代码的方法。

我使用Generic创建了此代码。 因此,这只是代码示例,我认为可以,我首先可以通过采用propertyName和字符串搜索来创建标准方法。 有用。

报关单

public class SampleClass
{
    public string SomeField = "Test";
}

public class ConfSampleClass2
{
    public Type Type { get; set; }
}

电话:

IQueryable result = GetCompaniesA<SampleClass2>("Name", "alpine");

方法 :

public IQueryable GetCompaniesA<T>(string propertyName, string search)
{
try
{                
IQueryable<T> results = null;
SampleClass2 sc2 = new SampleClass2();
List<SampleClass2> listSc2 = new List<SampleClass2>();
listSc2.Add(new SampleClass2() { Name = "alpine" });
listSc2.Add(new SampleClass2() { Name = "Statue" });
listSc2.Add(new SampleClass2() { Name = "Gateau" });

//listSc2.Where(c => c.Name == "alpine");
IQueryable<SampleClass2> queryableData = listSc2.AsQueryable<SampleClass2>();

// Compose the expression tree that represents the parameter to the predicate.
ParameterExpression pe = Expression.Parameter(typeof(T),typeof(T).Name);
Expression member = Expression.Property(pe, typeof(T).GetProperty(propertyName));
Expression left = Expression.Call(member, typeof(string).GetMethod("ToLower",   System.Type.EmptyTypes));
Expression right = Expression.Constant(search);
Expression e1 = Expression.Equal(left, right);                
MethodCallExpression whereCallExpression =
Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryableData.ElementType },
queryableData.Expression,
Expression.Lambda<Func<T, bool>>(e1, new ParameterExpression[] { pe }));                
return queryableData.Provider.CreateQuery(whereCallExpression);
}
catch (Exception ex)
{
throw ex;
}
}

但是我想进一步避免使用泛型,而是使用动态避免名称耦合。 因此,我修改了方法以获得这一方法:

电话:

Console.WriteLine(GetCompaniesDynamic(new ConfSampleClass2(){ Type=typeof(SampleClass2) },"Name", "alpine"));

方法 :

public IQueryable GetCompaniesDynamic(dynamic dynamicObj, string propertyName, string search)
{
try
{
    IQueryable results = null;
    SampleClass2 sc2 = new SampleClass2();
    List<SampleClass2> listSc2 = new List<SampleClass2>();
    listSc2.Add(new SampleClass2() { Name = "alpine" });
    listSc2.Add(new SampleClass2() { Name = "Statue" });
    listSc2.Add(new SampleClass2() { Name = "Gateau" });
    IQueryable<SampleClass2> queryableData = listSc2.AsQueryable<SampleClass2>();

    ParameterExpression pe = Expression.Parameter(dynamicObj.Type, dynamicObj.Type.Name);
    Expression member = Expression.Property(pe, dynamicObj.Type.GetProperty(propertyName));
    Expression left = Expression.Call(member, typeof(string).GetMethod("ToLower", System.Type.EmptyTypes));
    Expression right = Expression.Constant(search);
    Expression e1 = Expression.Equal(left, right);

    //the issue appears on this line ParameterExpression of type   //'EntityFrameworkGeolocationExpression.SampleClass2' cannot be used for delegate parameter //of type 'System.Object', I can't compile if I replace Object by Dynamic.
    MethodCallExpression whereCallExpression =
        Expression.Call(
            typeof(Queryable),
            "Where",
            new Type[] { queryableData.ElementType },
            queryableData.Expression,                        
            Expression.Lambda<Func<Object, bool>>(e1, new ParameterExpression[] { pe }));
    return results = queryableData.Provider.CreateQuery(whereCallExpression);                
}
catch (Exception ex)
{
    throw ex;
}
}

我试图找到一种方法来真正传递动态对象,因此在我的存储库中,我将用简单的查询用表达式3替换新闻,文章和对象。.我发现很多话题,有人问我,这是不可能的。 我接下来的下一步是通过演化参数来演化表达式三。

你能帮我走得更远吗?

最好的问候,亚历山大

正如我在评论中所说,我认为这是一个坏主意。 但是,有一种(未经尝试的)简单方法可以实现我认为您正在寻找的行为。

public IQueryable GetCompaniesDynamic(string table, string property, string search)
{
    using (var context = new DBContext())
    {
        return context.Database.SqlQuery("SELECT * FROM dbo." + table + " WHERE "
                                        + property + " = '" + search  + "'");
    }
}

您可以像这样使用它:

var companies = GetCompaniesDynamic("News", "Name", "myNews");

请注意,如果您不清理输入内容,拼写错误和错别字,直到应用程序在运行时崩溃,否则您就容易受到SQL注入的攻击,而只是忘记了调用什么字段。 我不知道为什么当您明确不想要实体框架提供的任何功能时,为什么使用实体框架。 但是,祝你好运。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM