在我当前的项目中,存储库使用EntityFramework,许多表作为新闻。 所以每次我们都有一个新的输入功能,我们创建相关的数据库,生成edmx,在存储库中创建一个新方法。 示例:db.News.Where(c => c.Name =='myNews'); db.Articles.Where(C => c.ArticleName == 'myArticle');
我搜索的方法是避免在每次代码真正相似时编写。
我使用Generic创建了这段代码。 所以它是一个代码示例,idead是可以的,我可以通过首先采用propertyName和string搜索来创建一个标准方法。有用。
声明
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;
}
}
我试图找到一种方法来真正传递一个动态对象,所以在我的存储库中,我将用一个表达式三替换用简单查询调用的新闻,文章和对象..我发现很多主题,并且有人,我读了这是不可能的。我的下一步是通过演化参数来演变表达式三。
你能帮助我走得更远吗?
祝你好运, 亚历山大
答案 0 :(得分:0)
正如我在评论中所说,我认为这是一个坏主意。但是,有一种(未经测试的)简单的方法来实现我认为你正在寻找的行为。
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注入攻击。当你明确地不想要它提供的任何功能时,我不知道你为什么使用实体框架。但祝你好运。