2013-03-08 2 views
0

Я хочу иметь приложение, в котором пользователь (обычно мощный пользователь) может вводить логическое выражение. Я хочу иметь возможность выполнять логическое выражение как в .NET, так и в SQL.Как настроить логическое выражение, которое может выполняться как на C#, так и на SQL, без зависимости от таких библиотек, как EntityFramework?

выражения сами не так уж трудно, они такие вещи, как:

  • страна сша
  • страна является одним из: Соединенные Штаты, Канада, Мексика
  • (страна сша) и (возраст 20)
  • (страна сша) ИЛИ ((возраст 20) и страна является одним из: соединенные штаты, Канада)

Мне нужно иметь возможность поддерживать основные вещи, такие как «in», equals, больше/меньше, между, содержит, startswith и т. Д. Я хочу иметь возможность компилировать в C# и запускать его против объекта типа dynamic и также иметь возможность компилировать выражение в SQL. Я бы включил результат в предложение where из очень конкретного запроса.

Я не хочу использовать Nhibernate или EntityFramework, я хочу, чтобы иметь возможность выполнять SQL напрямую.

UPDATE: Я уже знаю, что хочу выполнить его с помощью ADO.NET. Извините, если я не изложил это четко. Я просто хочу знать, какой хороший подход был бы для хранения логического выражения, которое может быть выполнено как в C#, так и в SQL. Я не забочусь о хранимых процедурах и параметризации (последнее очевидно и тривиально, как только я могу сгенерировать запрос). Пользователи, входящие в выражения, являются внутренними для моей компании, в основном для разработчиков и опытных пользователей.

Так что я думаю о том, чтобы использовать такие вещи, как деревья выражений, абстрактные деревья синтаксиса, LINQ и т. Д., Чтобы достичь этого. Я не хочу использовать ORM, но я хочу сделать что-то очень похожее на то, что ORM делают в выражениях LINQ для преобразования lambas в код для предложения WHERE.

UPDATE2: , как мы думаем, делать это до сих пор оказываем выражения вводятся как C# и хранятся в виде строк в базе данных. Когда мы хотим выполнить в .NET-контексте, мы скомпилируем в лямбда или выражение и, возможно, перекроем его в объект, который в качестве интерфейса с методом представляет логическое выражение interface IDynamicFilter { bool PassesFilter<SomePocoType>(poco); }. Или мы могли бы поместить POCO (ы) в IEnumerable и запустить LINQ .Where() с переданным lambda/expression, чтобы вытащить объекты, соответствующие фильтрам.

Для SQL это часть, в которой я более нечеткий. Мы хотим повторить то, что делают ORM, - посетите дерево Expresssion и превратите его в строку SQL. Нам не нужно поддерживать полный набор SQL. Нам нужно поддерживать только простые операторы, такие как группировка с круглыми скобками, AND/OR/NOT, in/not in, GT/LT/EQ/NEQ/между ними. Мы также хотим поддержать некоторые основные математические операции (a + b > c).

+0

«выполнить sql напрямую» ... вы хотите написать динамический запрос? Посмотрите ADO.NET. Похоже, вы хотите использовать 'SqlCommand'. Просто убедитесь, что вы его параметрируете для защиты от атак SQL-инъекций. –

+0

Что вы собираетесь выполнять в C# и sql? Я имею в виду, что будет представлять (возможные) значения страны, возраста и т. Д.? В sql вы «включили бы результат в предложение where очень специфического запроса». Как насчет C#? –

+0

Также вы не хотите использовать ORM, но вы хотите сделать то, что делают ORM. Можете ли вы объяснить, почему? –

ответ

0

Microsoft CRM имеет что-то вроде этого, где они дают вам поля формы и выпадающий список, определяющий то, что вы пытаетесь найти, и что ваш логический оператор, так что вы могли бы иметь.

Column: 
Select Column in Database 

Opeartor: 
> 
< 
>= 
<= 
LIKE 
= 
IN 
NOT IN 

Value: 
TextBox for user input 

Таким образом, вы должны принять пользовательский ввод и просто создать запросы на основе этого. Если вы не хотите использовать ORM, например Entity, вы можете использовать ADO.NET.

0

Если я правильно понимаю вашу проблему, вы можете сделать что-то вроде этого (и имейте в виду, я не рекомендую такого рода вещи для производства):

var query = "SELECT * FROM TABLE as T WHERE 1=1"; 

if ([some condition]) query += " AND T.CountryCode = 'USA'"; 
if ([some other condition]) query += " AND T.CountryCode IN ('USA', 'CAN', 'MEX')"; 
if ([yet another condition]) query += " AND T.CountryCode = 'USA' AND T.Age = 20"; 

using (var conn = new SqlConnection(connectionString)) 
{ 
    conn.Open(); 
    using (var comm = new SqlCommand(conn, query)) 
    { 
     var results = comm.ExecuteReader(); //returns an IDataReader you can loop through. 
    } 
} 

Я говорю снова, убедитесь, что вы параметризуя любые переменные, которые вы ищете, такой запрос весьма уязвим для SQL-инъекции. Это способ ленивого разработчика что-то делать, и может быть довольно опасным. Если вы хотите избежать ORM, такая логика должна быть в хранимой процедуре, в которую вы передаете параметры.

+0

Я не могу hardcode 'if''s, это 'не то, что я пытаюсь сделать. Я хочу динамически хранить булевы выражения в базе данных. Затем я хочу иметь возможность выполнить это определение в контексте C#, а также в контексте SQL. Свойства таблицы при выполнении в SQL всегда будут соответствовать свойствам объекта C#, свойства которого проверяются в булевом выражении. Я не знаю свойства во время компиляции. – DarkwingDev

+0

Это не то, что вы действительно можете сделать ... теоретически вы делаете какой-то сверхпрочный динамический SQL в своей базе данных, но я не могу представить ситуацию, когда это было бы желательным планом действий. ближайший практический эквивалент для этого - написать несколько хранимых процедур/представлений для ваших данных. Он не будет динамичным до уровня, который вы хотите, но он считается намного лучшей практикой по множеству причин. –

+0

Извините, но я не согласен с вами в том, что это невозможно, если вы не можете объяснить причину. Тот факт, что LINQ to SQL существует вообще, является доказательством того, что это было сделано. Это было сделано в ENtityFramework, и в NHIbernate, и даже в клиенте MongoDB C# (кроме того, что компилируется в запросы MongoDB, а не SQL). Я хочу, чтобы они делали то же самое, но с возможностью просто генерировать SQL-код в строку без того, чтобы эти фреймворки выполняли ее для меня. – DarkwingDev

 Смежные вопросы

  • Нет связанных вопросов^_^