Как создать универсальный WCF OperationContract для извлечения данных из таблицы SQL - PullRequest
2 голосов
/ 07 июля 2010

Мне было поручено создать интерфейс .net для таблицы, которая будет извлекать базу данных.

Одна из очевидных вещей, которые должен сделать интерфейс, - это извлечь данные из таблицы.

Итак ... Я мог бы написать функцию, которая просто делает Select * from MyTable; и затем возвращает результат.Однако таблица имеет десять столбцов, и кто-то, использующий интерфейс, может захотеть отфильтровать данные по одному или нескольким столбцам.Мне может понадобиться что-то вроде Select * from MyTable where LastName like 'A%';.Как я могу спроектировать мой интерфейс как гибкую единую точку входа для загрузки данных из таблицы?

Мне сказали, что любое решение, которое включает в себя удаление всей таблицы с сервера и последующую фильтрацию результатовв коде .net это недопустимо из-за проблем с пропускной способностью.

Примечание: Я также хотел бы добавить, что код, извлекающий данные из таблицы SQL, называется службой WCF;однако данные извлекаются, они должны быть возвращены вызывающей стороне как сериализуемые данные, а не как какие-либо ссылки.

Уточнение: Под "интерфейсом" я просто имел в виду функцию, которая являетсявызывается для извлечения данных из таблицы SQL.Я понимаю, что термин «интерфейс» немного сбивает с толку.Есть слово точно, что я делаю, но я не знаю, что это такое.

Ответы [ 3 ]

3 голосов
/ 07 июля 2010

Я рекомендую использовать LINQ to Entities .У него уже есть все проблемы эффективности использования полосы пропускания.

Обновление (для WCF): В этом случае я рекомендую Службы данных WCF (ранее называлось ADO.NET).Службы данных, ранее называвшиеся Astoria).Они используют протокол REST под названием oData интересным способом.По сути, вы реализуете сервис, предоставляя IQueryable<T> (например, используя LINQ to Entities), а затем вы можете использовать сервис, используя «LINQ to oData» (я только что придумал этот термин, но это идея).

Таким образом, ваши клиенты могут делать что-то вроде:

var beverages = from product in myDataService.Products
                where product.CategoryName = "Beverages"
                select product;

(при условии, что myDataService - это DataServiceContract, который указывает на вашу службу данных WCF).Этот запрос преобразуется в вызов oData, что-то вроде http://myHost/myWCFService.svc/Products?$filter=CategoryName%20eq%20'Beverages'.Строка запроса oData интерпретируется службой данных WCF и передается вашей реализации IQueryable<T>.Если это LINQ to Entities, то запрос передается в базу данных, поэтому фактический SQL-запрос выглядит примерно так: SELECT * FROM [Products] WHERE [Products].[CategoryName] = 'Beverages'.

Как видите, это невероятно мощная концепция, которая позволяет очень эффективнозапрос данных без опасности внедрения SQL.Есть и обратная сторона: поскольку разрешен любой тип запросов, такой подход может усложнить оптимизацию базы данных.Это также открывает возможность более простых атак DoS, хотя они могут быть ограничены.Так что это делает нашу жизнь программистов очень легкой, но некоторые администраторы БД не решаются ее принять.

0 голосов
/ 07 июля 2010

NHibernate, SubSonic, LINQ 2 SQL, Entity Framework, LLBLGen, Codus и многие другие.

Мне лично нравится NHibernate, с отображениями Fluent, но это может считаться излишним и имеет немного кривой обучения.

Такие библиотеки, как Sh # rp Architecture, Spring.NET и Castle Active Record, абстрагируют детали реализации NHibernate, так что вы можете сосредоточиться на Pocos и бизнесе, не заботясь о поддержке DAL.

0 голосов
/ 07 июля 2010

Я бы поместил 10 текстовых полей в форму, а затем создал бы запрос вроде:

string query = "select top 100 * from MyTable where 1=1 ";
if (!string.IsNullOrEmpty(txtLastName.Text))
    query += string.Format("and LastName like '%{0}%' ", txtLastName.Text);
if (!string.IsNullOrEmpty(txtFirstName.Text))
    query += string.Format("and FirstName like '%{0}%' ", txtFirstName.Text);

Предложение top гарантирует, что это никогда не загрузит более 100 строк.

Сделайте убедитесь, что выполните полученный запрос, используя пользователя с низким уровнем привилегий, или убедитесь, что пользователь не вводит одинарную кавычку ' в текстовое поле:)

...