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

C# 我应该如何从WCF服务解决方案访问SQL Server?,c#,.net,sql-server,wcf,C#,.net,Sql Server,Wcf,我有一些访问SQLServer2005的现有WCF代码,但老实说,我不信任开发人员的方法,所以我想知道如何正确和专业地完成这项工作。我需要能够将SQL语句传递给一个方法(在WCF服务中,而不是从客户端),该方法返回结果数据集(到WCF中调用它的方法,而不是客户端)。我对实体框架或其他抽象层不感兴趣。我需要运行SQL、DML,希望还有DDL 我还想知道如何管理连接 如果你愿意,请指出你对更好的选择的想法。我准备好听。 在配置文件中保存连接字符串 尽可能多地连接到数据库,这样您就不用担心了 在处理s

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

我还想知道如何管理连接

如果你愿意,请指出你对更好的选择的想法。我准备好听。

  • 在配置文件中保存连接字符串
  • 尽可能多地连接到数据库,这样您就不用担心了
  • 在处理sql连接时,请始终使用
    using

    使用(sqlConn=newsqlconnection(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;
    }
}
更新

下面是一个如何向客户端返回“数据集”的示例,我不建议这样做,但它会起作用:

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;
        }
    }
老实说,您不应该从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
        }
    }
}
在客户端:

ServiceClient proxy = new ServiceClient();
Customer myCustomer = proxy.GetCustomer(42);
您真的不应该考虑重用SQL连接。 数据库的连接池将为您处理此问题。创建/关闭与DB的连接是一项轻松的操作。 为每个webservice调用创建一个新连接将避免很多麻烦(连接生存期…等等)


尽可能多地使用无状态服务,这将为您节省大量时间(并发问题、对象生命周期管理…。

“我还想知道如何重新使用相同的连接[…]”-->听起来不是个好主意。无状态服务更易于维护,不易出现错误。注意,由于有了连接池,创建数据库连接是一项轻松的操作。正如@ken2k所说的,不要担心打开/关闭连接。打开和关闭都不会影响任何性能。这里有一个连接池来处理“问题”。谢谢大家,我已经编辑了我的问题。它是用来保存数据的对象,例如Employee类或Order类。。差不多吧。换句话说,实体。@ken2k的答案中的customer类是如何在WCF和客户机之间共享数据的一个很好的例子……谢谢HaLaBi,但是如何管理我不想创建实体的通用数据集呢。是否有一种方法可以使用ClientDataSet(Delphi术语,用于结果数据集-记录和字段)。您始终可以将数据集对象返回到客户端,但不建议这样做。谢谢,不用担心,它不会返回到客户端。我只想知道如何获取和使用它(在WCF服务中)。客户只会得到合同中定义的东西。+1表示您的“诚实”。。。但我在编辑的问题文本中澄清了sql不是从客户端传入的。我说的是在WCF服务中从一个方法到另一个方法的SQL语句。客户将仅限于公开合同。