簡體   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