2012-04-20 4 views
2

У меня есть некоторый код WCF, который обращается к SQL Server 2005, но, честно говоря, я пришел к недоверию к методам разработчика, поэтому я хочу знать, как это должно быть сделано правильно и профессионально. Мне нужно передать инструкцию SQL методу (в службе WCF, а не клиенту), который возвращает результирующий набор данных (к методу в WCF, который его вызвал, а не клиенту). Меня не интересуют рамки сущностей или другие уровни абстракции. Мне нужно запустить SQL, DML и, надеюсь, DDL.Как мне получить доступ к SQL Server из службы WCF?

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

Пожалуйста, указывайте свои мысли о лучших альтернативах, если вам так хочется. Я готов слушать.

+5

«Я также хочу знать, как повторно использовать одно и то же соединение [...]» -> Мне кажется, что это плохая идея. Безстоящие службы легче поддерживать и менее подвержены ошибкам. Обратите внимание, что создание соединения с БД является легкой работой благодаря пулу подключений. – ken2k

+0

Как сказал @ ken2k, не беспокойтесь об открытых/закрытых соединениях. Вы не получаете никакого удара, открывая и закрывая. Существует пул соединений для обработки «проблемы» – Steve

+0

Спасибо, я отредактировал мой вопрос. – Sam

ответ

6
  • Сохраните строку подключения в файле конфигурации.
  • Подключитесь к базе данных столько, сколько хотите, Connection Pool позаботится о том, чтобы вам не пришлось беспокоиться об этом.
  • Всегда используйте using при работе с sql-соединениями.

    Using (sqlConn = new SqlConnection(ConnString)) { }

  • Сделать свой собственный POCO которые вернуть результат клиенту, вы можете сделать их в отдельной сборке и разделить его в обоих проектах (WCF и клиента), или вы можете просто добавить их в WCF и когда вы создаете прокси на стороне клиента, у вас будет доступ к ним.

Вот макет образца:

public Poco Foo(long id) 
{ 
    try 
    { 
     using (SqlConnection SqlConn = new SqlConnection(ConnString)) 
     { 
      // execute your commands and do your stuff 
      return Poco; 
     } 
    } 
    catch (Exception ex) 
    { 
     Logger.Log(ex.ToString()); 
     return null; 
    } 
} 

UPDATE

Вот пример того, как вернуть «DataSet` к клиенту, я не рекомендую это, но это будет работать:

public DataSet Foo(long id) 
    { 
     try 
     { 
      using (SqlConnection SqlConn = new SqlConnection(ConnString)) 
      { 
       SqlCommand sqlCmd = new SqlCommand("Select * From users where [email protected]", SqlConn); 
       sqlCmd.Parameters.Add("@id", SqlDbType.BigInt).Value = id; 
       DataSet ds = new DataSet(); 
       using (SqlDataAdapter da = new SqlDataAdapter(sqlCmd)) 
       { 
        da.Fill(ds, "Users"); 
       } 

       return ds; 
      } 
     } 
     catch (Exception ex) 
     { 
      Logger.Log(ex.ToString); 
      return null; 
     } 
    } 
+0

+1 "POCOs"? пожалуйста, расшифруйте ... и спасибо за образец. – Sam

+0

http://en.wikipedia.org/wiki/Plain_Old_CLR_Object –

+0

Его объекты для хранения ваших данных, например, класса Employee или класса Order .. что-то в этом роде. другими словами Entity .. –

11

Честно говоря, вы не должны доступ SQL Server из службы WCF.

Вы должны доступ данные из службы WCF, не зная, есть SQL Server под капотом.

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

Что бы вы могли (должны) сделать, это написать службу, которая возвращает данные, которые вы действительно хотите вернуть. Например:

[DataContract] 
public class Customer 
{ 
    [DataMember] 
    public string Name { get; set; } 
} 

[ServiceContract] 
public interface IService 
{ 
    Customer GetCustomer(int customerId); 
} 

[ServiceBehavior] 
public class Service 
{ 
    [OperationContract] 
    public Customer GetCustomer(int customerId) 
    { 
     // Insert DB-related implementation of your query: 
     // - you could hard-code a SQL query 
     // - you could use Entity-Framework or other ORM 
     // 
     // First, create your connection to your database 
     // Then query 
     // Then close your connection 
     // 
     // Example with SQL connection 
     // Connection string comes from server configuration (app.config or whatever) 
     using (SqlConnection cn = new SqlConnection(connectionString)) 
     { 
      Customer res = new Customer(); 

      // query here 

      Customer.Name = XXX; // From DB result 
     } 
    } 
} 

На стороне клиента:

ServiceClient proxy = new ServiceClient(); 
Customer myCustomer = proxy.GetCustomer(42); 

Вы действительно не должны думать о повторном использовании соединений SQL. Пул соединений вашей базы данных будет обрабатывать это для вас. Создание/закрытие соединения с БД - это световая операция. Создание нового соединения для каждого вызова webservice позволит избежать ошибок в LOTS (срок службы соединения ... и т. Д.).

Использовать службы без гражданства как можно больше, это сэкономит вам много времени (проблемы параллелизма, управление жизненным циклом объекта ...).

+2

+1 для вашей «честности» ... но я уточнил в моем отредактированном тексте вопроса, что sql не передается от клиента. Я говорю о выражении SQL от одного метода к другому в службе WCF. Клиент будет ограничен открытыми контрактами. – Sam

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