2009-03-02 2 views
1

У меня есть идея, что использование SQL VIEWS для абстрактных простых вычислений базы данных (например, подсчет отношения) достаточно, и вам не нужны процедуры (== процедурные код)ADO.net без написания SQL (особенно WHERE)

простой SQL вид + а где раздел >> хранимая процедура с параметрами иногда

в то время делая этот момент я представлял себе способ получения таблицы/просматривать данные без написания SQL и без написания предложения where ..

Но, к моему удивлению, в ADO.NET 2.0 или более поздних версиях не существует способа выполнить это.

Позвольте мне сказать вам, что я пробовал:

  • SqlDataAdapter + SqlCommandBuilder еще требует, чтобы написать «SELECT ... FROM» и ИНЕКЕ в строках (плюс, если вы поместите " где ', у вас не так много пользы от Update/Insert/DeleteCommand)

  • Набранные DataSet только позволяют вам извлекать _entire DataTable_s и затем применять к ним фильтры. Фильтры являются строками, не избегая помощи ...

  • SQL to Entities выглядели многообещающими, но они, похоже, должны быть ограничены MSSQL, генерировать раздутые SQL-запросы, генерировать совершенно новый стек DAO (помимо существующих классов Domain Model), reqiuire .net 3.5+ за все это и т.д. (то есть, все эти недостатки для меня)

Другие ORMs имеют схожие проблемы, как SQL для лиц.

Что я ищу является сильными типизированными методами доступа к таблицам базы данных/просмотров что:

  • не приходит с другим набором объектов DAO (ПОЦЕЛУЙ)
  • позволяют мне запрос к таблице без написания «вЫБИРАЕТ» в строках (сильного типизированных)
  • позволяет мне фильтр (ГДЕ) таблица с должным сбежавших параметров (И не извлекая все данные заранее)
  • позже может выпустить обновления/вставки/удаления

Я довольно новыми для .Net, но не глуп: ли это существует?

Спасибо.

ответ

2

Subsonic имеет довольно легкий query tool, который можно использовать для прямого запроса к базе данных с помощью объекта Query, который абстрагирует SQL. Если вы хотите, вы также можете использовать средство генерации кода для сопоставления таблиц базы данных с POCOs или для создания строго типизированной схемы (для имен столбцов/таблиц и т. Д.).

+0

Мне это нравится (например, http://subsonicproject.com/docs/Simple_Query_Tool) – Vlagged

1

Если вы не хотите писать предложение WHERE, одним из способов является использование объекта Filter и добавление необходимых условий.Например:

 var sc = new Filter(); 
     sc.Add("Contacttitle", "Sales Agent"); 
     sc.Add("city", "london", Logical.Or); 
     var customers = D2Bk.Fetch(sc, new Customers()); 

Но вы не хотите использовать объекты DAO (Клиенты выше такой), так что вы должны написать заявление SQL и указать пункт, где:

 DataSet ds = D2Bk.Fetch("SELECT * FROM Customers WHERE [email protected] OR [email protected]", "Sales Agent", "london"); 
+0

В терминах, которые вы используете: мне бы хотелось: D2Bk.Fetch («Клиенты»); , а затем примерно следующее: sc.Add ("city", "london", Logical.Or); – Vlagged

+0

Вы имеете в виду, после выборки всех строк, фильтрация city = london в наборе результатов? Это не будет работать хорошо, но это возможно. –

+0

Нет, я имею в виду, мне нравится способ указать имя таблицы и добавление условия. (Извините, что ответили на это поздно). И да, ни один DAO не будет в порядке. – Vlagged

1

я сделал что-то вроде этого с хранимой процедурой один раз. В принципе, я хотел указать любую перестановку полей, которые должны совпадать в моем предложении WHERE, но я не хотел писать 100 sprocs с немного разными списками параметров и где предложения.

Итак, я сделал что-то вроде этого:

CREATE PROCEDURE [GetSimpleCustomers] 
(
@ID varchar(50) = null, 
@Name varchar(50) = null, 
@IsActive bit = null, 
@Address1 varchar(50) = null, 
@Address2 varchar(50) = null, 
@City varchar(50) = null, 
@State varchar(50) = null, 
@Zip varchar(50) = null 
) 
AS 

SELECT ID, Name, IsActive, Address1, Address2, City, State, Zip 
FROM SimpleCustomerExample 
WHERE (ID = @ID OR @ID is NULL) 
AND (Name = @Name OR @Name is NULL) 
AND (IsActive = @IsActive or @IsActive is NULL) 
AND (Address1= @Address1 or @Address1 is NULL) 
AND (Address2= @Address2 or @Address2 is NULL) 
AND (City= @City or @City is NULL) 
AND (State= @State or @State is NULL) 
AND (Zip= @Zip or @Zip is NULL) 

Это позволит вам вызвать sproc в коде, и только передать Params вы заинтересованы в фильтрации на, а остальные не будут учитываться, если вы оставляете их пустыми.

Таким образом, вы можете сделать что-то вроде

public List<SimpleCustomer> GetAllCustomersFromOhio() 
{ 
    List<SimpleCustomer> list = new List<SimpleCustomer>(); 
    using (SqlCommand cmd = new SqlCommand(blah blah)) 
    { 
     cmd.Parameters.AddWithValue("State", "Ohio");//or "OH" depending on your convention 
     using(IDataReader oDR = cmd.ExecuteReader()) 
     { 
      //hydrate your list of SimpleCustomers from the record set. 
     } 
    } 
    return list; 
} 

EDIT: В ответ на комментарий: Вы можете достаточно легко изменить GetSimpleCustomers быть DeleteSimpleCustomers путем изменения

SELECT <columns> FROM SimpleCustomers 

в

DELETE FROM SimpleCustomers 

и сохранить та же логика. То же самое верно для обновления. Кроме того, я отвечу на вопрос вопросом: сколько у вас таблиц, которые действительно нуждаются в этом уровне пользовательской фильтрации? Синтаксис был бы настолько похож, что вы могли бы избить все это за один день (или меньше, если бы вы собрали простой скрипт, чтобы написать его для вас).

+0

Ну, это интересное решение, если у вас есть одна таблица, забитая этими типами запросов. Но сделаете ли вы это для всех таблиц? Плюс, меня просто интересуют все их. Выберите/Вставьте/Удалите утверждения. Благодарю. – Vlagged

1

Я бы предположил, что вы просмотрели LINQ и ADO.Net Data Services, и это не соответствует вашим требованиям?

Native ADO.Net - поставщик базы данных, поэтому он предоставляет прямой SQL-интерфейс в базовые источники данных. Существуют различные решения на основе CRUB, которые имитируют то, что вы предлагаете в разной степени.

У нас есть сильная внутренняя тенденция оставить базу данных в команде базы данных и использовать веб-службы в качестве основного интерфейса для наших баз данных, главным образом из-за базы данных Delphi, которая все еще нуждается в поддержке.

На самом деле я не могу поверить, что забыл добавить ADO.Net Entity Framework, который используется службами данных ADO.Net среди прочих. Существует также поставщик LINQ to Entities.

+0

Спасибо за ваш ответ. Я просмотрел службы ADO.NET Data, но, похоже, это сервис-ориентированный слой поверх ADO.NET. Говоря о том, что ADO.NET является поставщиком баз данных, вы правы, но он включает в себя «сахар», такой как DbCommandBuilder, который идет в том направлении, которое я хотел, но не настолько далеко :( – Vlagged

+0

Простой комментарий, однако признаю, что сомневаюсь, что вы найдете решение, которое вам нужно, поскольку оно на самом деле противоположно тому, что пытается достичь ADO.Net. – BinaryMisfit

2

Я не очень верю, что то, что вы хотите сделать, это достижимо без использования какой-то ORM, или специализированный DSL с компилятором, который каким-то образом знает о вашей схемы базы данных, информацию о типе/колонки и т.д.

Учтите, что C# является языком общего назначения, а его компилятор полностью не знает о ваших типах баз данных, поэтому вы не можете связывать их, не используя какой-либо уровень абстракции, который обычно включает специальные SQL-запросы (строки), NHibernate или аналогичные файлы сопоставления (больше строк) и/или DAO.

1

Если вы используете строго типизированные DataSets, вы можете создавать параметризованные запросы в Visual Studio Editor путем добавления идентификаторов с префиксом @ в запросе. Создайте файл XSD DataSet в Visual Studio и создайте новую таблицу под названием «Продукты», а затем добавьте к ней новый запрос.

Например:

select * from Products where Category = @category; 

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

+0

Сильно типизированные наборы данных ?! Если бы у меня был rep, я бы использовал -1 для этого. Наборы данных являются одним из величайших пороков старой школы ADO. Чрезмерные ресурсы, раздутые, тесно связанные с db и т. Д. Они могут быть одобрены в упрощенном прототипе, но в реальном критически важном корпоративном решении избегайте все расходы. –

+0

для серьезного кода, да, вы бы избегали их любой ценой. Но если вы хотите собрать быстрый прототип или временное решение, пока вы не придумаете лучшую схему доступа к данным, тогда это работает. Если, как и в этом случае, вы не хотите использовать ORM, то это возможное решение. Не решение BEST, а решение. –

1

Недавно я написал запрос 'framework' для генерации предложений SQL where.

Основным компонентом является класс BaseQueryArgs с функцией ToWhereClause(), которая использует отражение для преобразования свойств в разделы строк. Это необходимо для обработки работы экранирования и правильного форматирования значений.

Любой класс, наследующий BaseQueryArgs, просто должен объявлять общедоступные свойства, и вы получите строго типизированный объект запроса. Для дополнительных свойств вы устанавливаете значение nullable (тип ref или Nullable <>), а генератор SQL фильтрует нулевые значения.

Вы можете использовать пользовательские атрибуты, чтобы определить дополнительные функции для каждого свойства:

  • пользовательского имени столбца, который отличается от имени свойства
  • пользовательских обработки (например, значения даты значения используется как между тестовым выражение)

Это может быть использовано для создания запросов с сильно типизированным объектом запроса следующим образом:

MyCustomQueryArgs args = new MyCustomQueryArgs 
{ 
    ProductFamilyID = 17, 
    Region = Regions.Northwest, 
    Active = true 
}; 

List<Product> product = QueryProcessor.GetProductsWhere(args); 

GetProductsWhere(), очевидно, вызовет некоторый метод данных, который обращается к представлению с помощью сгенерированного SQL.

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

Это очень «рулон», но это дает вам свободу в настройке его для ваших нужд и не включает в себя множество тяжелых оберток ORM/DAO.

+0

это звучит интересно, но доступно ли кому-нибудь еще? – Vlagged

+1

Он предлагает решение, которое сработало для него, и предлагая вам написать свое собственное, если вам это нравится. –

+0

Да, я предлагал легко расширяемое пользовательское решение. Я бы передал несколько методов, но я уверен, что мой работодатель владеет всем этим. – jpj625

0

Посмотрите Mindscapes Lightspeed продуктов

Он строит stongly типизированные модели queriable LINQ, что приводит к эффективному коду SQL accross различные СУБД и включает в себя поддержку Memcached и Lucene

0

я использовал XPO по нескольким проектам и их новая версия имеет лучшую поддержку запросов.

http://www.devexpress.com/Products/NET/ORM/

Реализация, как и все они не без недостатков, однако.

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