2014-11-04 2 views
1

Недавно я оказался на C#, выполняя некоторые SQL. Это не совсем моя область знаний. Я написал код, который выглядит довольно уродливым, и я не могу найти лучшего решения в любом месте. Многие из ответов здесь на SO создают риски инъекций SQL и по существу делают то же самое, что и я, делая так или иначе. Ситуация заключается в том, что у меня есть форма, которую пользователь предоставляет список идентификаторов магазина в форме. Когда они нажимают кнопку, экспорт CSV будет сгенерирован с использованием магазинов, которые они предоставляют в качестве критериев исключения для запроса. То, как я это сделал, - это настроить мою строку SQL как константу, а затем использовать построитель строк для динамического добавления @X в предложении IN. Код выглядит довольно плохо, но для быстрого объяснения это быстрый фрагмент. Например, говорят, что SQL-запрос этоЛучшая практика для динамического построения переменной длины IN SQL в C#

private readonly String _SELECT_UNEXPECTED_TOTES = "SELECT * FROM TABLE WHERE TABLE.Store IN "; 

Я тогда сделайте следующее (хранит это массив строк, С.Б. является строка строитель):

   //get enough room for all the stores 
       var sqlParams = new SqlParameter[stores.Length]; 
       conn.Open(); 
       //append our query 
       sb.Append(_SELECT_UNEXPORTED_TOTES); 
       //open the IN list 
       sb.Append("("); 
       //build the in list 
       int I = 0; 
       foreach (String s in stores) 
       { 
        sb.Append("@"); 
        sb.Append(I); 
        sb.Append(","); 
        I++; 
       } 
       //trim the trailing , 
       sb.Length -= 1; 
       sb.Append(")"); 
       //make the actual parameters 
       I = 0; 
       foreach (String s in stores) 
       { 
        sqlParams[I] = new SqlParameter("@" + I, SqlDbType.VarChar); 
        sqlParams[I].Value = s; 
        I++; 
       } 

Позже в коде я затем использовать эти параметры SQL в объекте SqlStatement. Обеспечивает ли .NET лучший способ достичь этого? Я не очень много знаю о .NET-объектах SQL, и для всех знаю, что это решение может быть столь же плохим, как простая замена строки ... Любые советы приветствуются.

+1

Я не знаю точно, как это сделать, но, согласно вашим словам, вы можете попробовать EntityFramework. –

+0

@IsThatSo Приложение, в котором работает, довольно мало. Своя быстрая работа для клиента, и я думаю, после просмотра видео Entity Framework, что Entity Framework является серьезным излишеством. Мне не нужно много знать о БД в этом приложении. Его просто, получите список ID, запрос, а затем выплюнуть CSV. Я надеялся на решение с прямым проходом, которое не требует разработки API. –

+0

Ваше решение довольно простое. присоединяясь к строкам, вы можете использовать 'String.Join («, », магазины)', чтобы сделать ваш код «лучше». –

ответ

0

Я не верю, что это проще с помощью ADO.NET. Но, как некоторые другие пользователи упомянули, что Entity Framework сделало бы это значительно более чистым, и его действительно нетрудно настроить, особенно в небольшом приложении. Это превратит ваш код выше в:

var data = context.TABLE.Where(t => stores.Contains(t.Store)).ToList(); 
0

Вот гораздо более LINQ-й способ для достижения этой цели:

string[] storeIds = { "1Store", "2Store", "RedStore", "BlueStore" }; 
using (SqlCommand cmd = new SqlCommand()) 
{ 
    var paras = storeIds.Select((store, index) => new 
     { 
      name = String.Format("@p{0}", index), 
      value = store 
     }); 
    StringBuilder sb = new StringBuilder(); 
    sb.Append("select * from myTable"); 
    sb.Append(" where myTable.storeid in ("); 
    sb.Append(String.Join(",", paras.Select(p => p.name).ToList())); 
    sb.Append(")"); 
    cmd.CommandText = sb.ToString(); 
    foreach (var para in paras) 
    { 
     cmd.Parameters.AddWithValue(para.name, para.value); 
    } 
    cmd.Connection = conn; 
    // Now do whatever you want with the command ... 

«Магия» является использование Enumerable.Select<TSource, TResult> Method (IEnumerable<TSource>, Func<Source, Int32, TResult>) перегрузки, которая дает вам доступ к индексу, а также к значению элементов в вашем массиве идентификаторов.

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

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