J'essaye de construire une requête Linq vers Sql dynamique et ça marche plutôt bien, sauf pour invoquer la méthode SqlMethods.Like. Mon code est ci-dessous et le corps de la déclaration de LINQ généré ressemble à ceci:Linq dynamique utilisant SqlMethods.Like
Body = {((((log.ClientCode == "C1") OrElse
(log.ClientCode == "C2")) AndAlso
(log.Source == "S1")) AndAlso Like("Message", "%1%"))}
Comme vous pouvez le voir, il tente d'appeler « Comme » sans la classe SqlMethods. Une idée de ce que je fais mal ??
public IEnumerable<ILog> Get(int pageNumber, int pageCount,
List<string> clientCodes, List<string> sources, List<LogLevel> logLevels,
string messageContains, string userNameContains,
DateTime? dateStart, DateTime? dateEnd)
{
var expressions = new List<Expression>();
ParameterExpression pe = Expression.Parameter(typeof(Data.Logging.Log), "log");
if (clientCodes != null && clientCodes.Count > 0)
{
expressions.Add(CreateClientCodeExpression(pe, clientCodes));
}
if (sources != null && sources.Count > 0)
{
expressions.Add(CreateSourceExpression(pe, sources));
}
if (logLevels != null && logLevels.Count > 0)
{
expressions.Add(CreateLogLevelExpression(pe, logLevels));
}
if (!string.IsNullOrWhiteSpace(messageContains))
{
expressions.Add(CreateMessageExpression(pe, messageContains));
}
Expression exp = null;
if (expressions.Count > 0)
{
exp = expressions[0];
}
for (var i = 1; i < expressions.Count; i++)
{
exp = Expression.AndAlso(exp, expressions[i]);
}
var predicate = Expression.Lambda<Func<Data.Logging.Log, bool>>(exp, pe);
var results = DbContext.Logs.Where(predicate).ToList();
foreach (var result in results)
{
yield return ConvertDbLogToLog(result);
}
}
private Expression CreateClientCodeExpression(ParameterExpression pe, List<string> clientCodes)
{
Expression result = null;
clientCodes.ForEach(cc =>
{
MemberExpression me = Expression.Property(pe, "ClientCode");
ConstantExpression ce = Expression.Constant(cc);
if (result == null) { result = Expression.Equal(me, ce); }
else { result = Expression.OrElse(result, Expression.Equal(me, ce)); }
});
return result;
}
private Expression CreateSourceExpression(ParameterExpression pe, List<string> sources)
{
Expression result = null;
sources.ForEach(s =>
{
MemberExpression me = Expression.Property(pe, "Source");
ConstantExpression ce = Expression.Constant(s);
if (result == null) { result = Expression.Equal(me, ce); }
else { result = Expression.OrElse(result, Expression.Equal(me, ce)); }
});
return result;
}
private Expression CreateLogLevelExpression(ParameterExpression pe, List<LogLevel> logLevels)
{
Expression result = null;
logLevels.ForEach(l =>
{
MemberExpression me = Expression.Property(pe, "LogLevel");
ConstantExpression ce = Expression.Constant(l.ToString());
if (result == null) { result = Expression.Equal(me, ce); }
else { result = Expression.OrElse(result, Expression.Equal(me, ce)); }
});
return result;
}
private MethodCallExpression CreateMessageExpression(ParameterExpression pe, string message)
{
return Expression.Call(typeof(SqlMethods).GetMethod("Like", new[] { typeof(string), typeof(string) }),
Expression.Constant("Message"), Expression.Constant(string.Format("%{0}%", message)));
}
Ne devrait pas être une propriété comme dans d'autres conditions? –
Quelle est votre déclaration d'origine? –
@IvanStoev Lorsque j'apporte cette modification, j'obtiens cette exception: LINQ to Entities ne reconnaît pas la méthode 'Boolean Like (System.String, System.String)', et cette méthode ne peut pas être traduite en expression de magasin. –