Desidero creare un'espressione dinamica di linq per la clausola SQL in EF 6.0 con il codice approc. Nota che sono nuovo per le espressioni. Quello che voglio ottenere èAlbero di espressioni di query linq dinamiche per la clausola SQL IN utilizzando il framework Entity
select * from Courses where CourseId in (1, 2, 3, 4)
//CourseId is integer
La query di linq normale si presenta così. Ma voglio interrogare in modo dinamico
string[] ids = new string[]{"1", "2", "3", "4"};
var courselist = DBEntities.Courses.Where(c => ids.Contains(SqlFunctions.StringConvert((decimal?)c.CourseId)))
Ci sono due modi per fare espressione dinamica.
1) uno modi è quello di collegare attraverso ids e rendere le espressioni
Il codice di seguito creerà la seguente espressione in vista di debug
{f => ((StringConvert(Convert(f.CourseId)).Equals("23") Or StringConvert(Convert(f.CourseId)).Equals("2")) Or StringConvert(Convert(f.CourseId)).Equals("1"))}
espressione dinamica è
var param = Expression.Parameters(typeof(Course), "f")
MemberExpression property = Expression.PropertyOrField(param, "CourseId");
MethodInfo mi = null;
MethodCallExpression mce = null;
if (property.Type == typeof(int))
{
var castProperty = Expression.Convert(property, typeof(double?));
var t = Expression.Parameter(typeof(SqlFunctions), "SqlFunctions");
mi = typeof(SqlFunctions).GetMethod("StringConvert", new Type[] { typeof(double?) });
mce = Expression.Call(null,mi, castProperty);
}
mi = typeof(string).GetMethod("Equals", new Type[]{ typeof(string)});
BinaryExpression bex = null;
if (values.Length <= 1)
{
return Expression.Lambda<Func<T, bool>>(Expression.Call(mce, mi, Expression.Constant(values[0]), param));
}
//var exp1 = Expression.Call(mce, mi, Expression.Constant(values[0]));
for (int i = 0; i < values.Length; i++)
{
if (bex == null)
{
bex = Expression.Or(Expression.Call(mce, mi, Expression.Constant(values[i])), Expression.Call(mce, mi, Expression.Constant(values[i + 1])));
i++;
}
else
bex = Expression.Or(bex, Expression.Call(mce, mi, Expression.Constant(values[i])));
}//End of for loop
return Expression.Lambda<Func<T, bool>>(bex, param);
2) Il secondo modo in cui che ho provato (debug view)
{f => val.Contains("23")} //val is parameter of values above
L'espressione dinamica ESSIONE per sopra che ho provato è
var param = Expression.Parameters(typeof(Course), "f")
MemberExpression property = Expression.PropertyOrField(param, "CourseId");
var micontain = typeof(Enumerable).GetMethods().Where(m => m.Name == "Contains" && m.GetParameters().Length == 2).Single().MakeGenericMethod(typeof(string));
var mc = Expression.Call(micontain, Expression.Parameter(values.GetType(), "val"), Expression.Constant("2"));//NOTE: I haven't use CourseId for now as i am getting conversion error
return Expression.Lambda<Func<T, bool>>(mc, param);
ottengo i seguenti errori
- LINQ alle entità non riconosce il metodo 'System.String StringConvert (System.Nullable`1 [System.Double]) "metodo, e questo metodo non può essere tradotto in un'espressione di negozio quando utilizzo la prima metodologia . So che non posso usare ToString con EF questo è il motivo per cui ho usato SqlFunctions ma non funziona per me.
- Il parametro 'val' non era legato in LINQ to Entities specificato tua ricerca espressione usando secondo la metodologia
sto cercando questo da ultimi 4 giorni. L'ho cercato su google ma non ho trovato nessuna soluzione adatta. Mi aiuti per favore.
So bene che restituisca IQuerable elenco non reale. ma non hai ricevuto la mia domanda. Voglio fare la stessa cosa ids.Contains (c.CourseId) usando dinamicamente l'albero delle espressioni – Ali