Я ищу систему, в которой используются условия, которые "строят", а затем возвращают полученные данные обратно из базы данных.В настоящее время существует хранимая процедура, которая генерирует SQL на лету и выполняет его.Это особая проблема, которую я хочу устранить.
Моя проблема заключается в том, что у меня может быть несколько полей в моих критериях, и для каждого из этих полей может быть 1 или более значений сразные потенциальные операторы.
Например,
from t in Contacts
where t.Email == "email@domain.com" || t.Email.Contains ("mydomain")
where t.Field1 == "valuewewant"
where t.Field2 != "valuewedontwant"
select t
Поле, критерии и оператор хранятся в базе данных (и List<FieldCriteria>
) и могут выглядеть примерно так (на основе выше);
Email, Equals, "email@domain.com"
Email, Contains, "mydomain" Field1,
Equals, "valuewewant" Field2,
DoesNotEqual, "valuewedontwant"
или
new FieldCriteria
{
FieldName = "Email",
Operator = 1,
Value = "email@mydomain.com"
}
Итак, используя имеющуюся у меня информацию, я хочу иметь возможность построить запрос с любым количеством условий.Я видел предыдущие ссылки на Dynamic Linq и PredicateBuilder, но не могу представить это как решение моей собственной проблемы.
Будем благодарны за любые предложения.
Обновление
Следуя предложению о Dynamic Linq, я придумал очень простое решение, использующее один оператор, 2 поля и несколько критериев.Немного грубовато на данный момент, как написано в LinqPad, но результаты именно такие, как я хотел;
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 = "email1@domain.com"
});
conditions.Add(new Condition {
Field = "Email",
Operator = Operator.Equals,
Value = "email2@domain.com"
});
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());
}
}
С сгенерированным SQL;*
Formatted Condition For Email: Email="email1@domain.com"||Email="email2@domain.com"
Formatted Condition For Field1: Field1="Chris"
Просто нужно очистить это и добавить других операторов, и это выглядит хорошо.
Если у кого-то есть какие-либо комментарии по этому поводу, любой вклад будет оценен