Dynamique requête linq avec plusieurs inconnues critères

Je suis à la recherche de mettre en œuvre un système permettant d'utiliser que la "construction" des conditions et de retourner ensuite les données obtenues de la base de données. À l'heure actuelle, il existe une procédure stockée qui génère le SQL à la volée et l'exécute. C'est une question en particulier que je veux supprimer.

Mon problème vient du fait que je peux avoir plusieurs champs dans mes critères, et pour chacun de ces domaines, il pourrait y avoir 1 ou plusieurs valeurs, avec différents opérateurs potentiels.

Par exemple,

from t in Contacts 
where t.Email == "[email protected]" || t.Email.Contains ("mydomain")
where t.Field1 == "valuewewant"
where t.Field2 != "valuewedontwant"
select t

Le terrain, les critères et l'opérateur sont stockées dans la base de données (et List<FieldCriteria>) et serait quelque chose comme ceci (basé sur la ci-dessus);

Email, Equals, "[email protected]"
Email, Contains, "mydomain" Field1,
Equals, "valuewewant" Field2,
DoesNotEqual, "valuewedontwant"

ou

new FieldCriteria
{
FieldName = "Email",
Operator = 1, 
Value = "[email protected]"
}

Donc, en utilisant les informations que j'ai, je veux être en mesure de construire une requête avec un certain nombre de conditions. J'ai vu des précédentes liens Dynamiques Linq et PredicateBuilder, mais je ne suis pas en mesure de se le représenter comme une solution à mon problème.

Toutes les suggestions seraient appréciées.

Mise à jour

À la suite de la suggestion au sujet de Dynamique Linq, je suis venu avec une très solution de base, à l'aide d'un Opérateur Unique, avec 2 Champs et Critères multiples. Un peu brut pour le moment codé en LinqPad, mais les résultats sont exactement ce que je voulais;

enum Operator
{
Equals = 1,
}
class Condition
{
public string Field { get; set; }
public Operator Operator { get; set;}
public string Value { get; set;}
}
void Main()
{
var conditions = new List<Condition>();
conditions.Add(new Condition {
Field = "Email",
Operator = Operator.Equals,
Value = "[email protected]"
});
conditions.Add(new Condition {
Field = "Email",
Operator = Operator.Equals,
Value = "[email protected]"
});
conditions.Add(new Condition {
Field = "Field1",
Operator = Operator.Equals,
Value = "Chris"
});
var statusConditions = "Status = 1";
var emailConditions = from c in conditions where c.Field == "Email" select c;
var field1Conditions = from c in conditions where c.Field == "Field1" select c;
var emailConditionsFormatted = from c in emailConditions select string.Format("Email=\"{0}\"", c.Value);
var field1ConditionsFormatted = from c in field1Conditions select string.Format("Field1=\"{0}\"", c.Value);
string[] conditionsArray = emailConditionsFormatted.ToArray();
var emailConditionsJoined = string.Join("||", conditionsArray);
Console.WriteLine(String.Format("Formatted Condition For Email: {0}",emailConditionsJoined));
conditionsArray = field1ConditionsFormatted.ToArray();
var field1ConditionsJoined = string.Join("||", conditionsArray);
Console.WriteLine(String.Format("Formatted Condition For Field1: {0}",field1ConditionsJoined));
IQueryable results = ContactView.Where(statusConditions);
if (emailConditions != null)
{
results = results.Where(emailConditionsJoined);
}
if (field1Conditions != null)
{
results = results.Where(field1ConditionsJoined);
}
results = results.Select("id");
foreach (int id in results)
{
Console.WriteLine(id.ToString());
}
}

Avec une instruction SQL générée;

-- Region Parameters
DECLARE @p0 VarChar(1000) = 'Chris'
DECLARE @p1 VarChar(1000) = '[email protected]'
DECLARE @p2 VarChar(1000) = '[email protected]'
DECLARE @p3 Int = 1
-- EndRegion
SELECT [t0].[id]
FROM [Contacts].[ContactView] AS [t0]
WHERE ([t0].[field1] = @p0) AND (([t0].[email] = @p1) OR ([t0].[email] = @p2)) AND ([t0].[status] = @p3)

Et De Sortie De La Console:

Formatted Condition For Email: Email="[email protected]"||Email="[email protected]"
Formatted Condition For Field1: Field1="Chris"

Juste besoin de nettoyer cette et ajouter les autres Opérateurs et il est à la recherche de bonnes.

Si quelqu'un a des commentaires sur cette mesure, toute entrée serait appréciée

OriginalL'auteur ChrisBint | 2011-06-23