我应该如何从WCF服务解决方案访问SQL Server?

Sam*_*Sam 2 .net c# sql-server wcf

我有一些现有的WCF代码访问SQL Server 2005,但说实话,我不相信开发人员的方法,所以我想知道如何正确和专业地完成.我需要能够将SQL语句传递给返回结果数据集的方法(在WCF服务内,而不是从客户端)(返回到调用它的WCF中的方法,而不是客户端).我对实体框架或其他抽象层不感兴趣.我需要运行SQL,DML,以及希望DDL.

我也想知道如何管理连接.

如果您愿意,请指出您对更好的替代品的想法.我准备好听.

ken*_*n2k 12

老实说,您不应该从WCF服务访问SQL Server.

您应该从WCF服务访问数据,而不知道底层有SQL Server.

公开接受SQL语句的Web服务看起来对我来说绝对是一个糟糕的主意.出于多种原因(安全性等等),您不希望将数据库公开给服务的客户端.

您可以(应该)做的是编写一个返回您实际想要返回的数据的服务.例如:

[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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在客户端:

ServiceClient proxy = new ServiceClient();
Customer myCustomer = proxy.GetCustomer(42);
Run Code Online (Sandbox Code Playgroud)

你真的不应该考虑重用SQL连接.数据库的连接池将为您处理此问题.创建/关闭与DB的连接是一项轻量级操作.为每个Web服务调用创建一个新连接将避免很多麻烦(连接生命周期......等).

尽可能使用无状态服务,它将为您节省大量时间(并发问题,对象生命周期管理......).

  • +1为你的"诚实"...但我在我编辑的问题文本中澄清了sql没有从客户端传入.我在谈论在WCF服务中从一种方法到另一种方法的SQL语句.客户将仅限于暴露的合同. (2认同)

小智 6

  • 将连接字符串保存在配置文件中.
  • 尽可能多地连接到数据库,连接池将负责您不必担心它.
  • 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

这是一个如何将'DataSet`返回给客户端的示例,我不推荐这个,但它会工作:

public DataSet Foo(long id)
    {
        try
        {
            using (SqlConnection SqlConn = new SqlConnection(ConnString))
            {
                SqlCommand sqlCmd = new SqlCommand("Select * From users where userid=@id", 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;
        }
    }
Run Code Online (Sandbox Code Playgroud)