如何从C#Web服务在Access 2007文件中执行SQL查询?

时间:2009-06-01 15:01:59

标签: web-services ms-access-2007

我们希望在IIS中拥有一个托管的C#Web服务,我可以将其传递给方法SOL Query,并在存在于包含Web服务和返回数据的同一服务器中的Access 2007 DB文件上执行查询。

我们已经使用以下代码

<%@ WebService Language="C#" 
  CodeBehind="~/App_Code/Service.cs" 
  Class="Service" %>
using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;

using System.Data;
using System.Data.OleDb;
using System.IO;

public class Service : System.Web.Services.WebService
{
    [WebMethod]
    public DataSet ExecuteQuery(string sqlQuery) 
    {
        OleDbConnection conn = new OleDbConnection(
             @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + 
             @"C:\Folder\Database2.accdb;Persist Security Info=False;");

        OleDbDataAdapter da = new OleDbDataAdapter(sqlQuery, conn);
        DataSet ds = new DataSet();
        da.Fill(ds);            
        return ds;
    }

}

但是当我们调用这个方法时,页面只显示在Load(正在进行中)但没有任何数据返回或Exception。

2 个答案:

答案 0 :(得分:6)

我可以建议您对设计和代码结构进行一些改进吗?

1。重新评估将其设为网络服务的原因。你可以将它编译成类库程序集(.dll)并从其他项目中引用它吗?进行Web服务调用的开销或时间成本远大于对另一个库的引用。是的,您必须处理Access的配置问题。

2. 重新考虑您希望在每次调用时返回DataSet的原因。这是一篇关于ADO.NET DataSet的缺点的优秀文章:www.4guysfromrolla.com/articles/050405-1.aspx

3. 如果没有先评估或参数化,请不要执行任何给定的字符串。我理解创建一个能够处理所有数据库查询的层的愿望,你应该为这个想法鼓掌。如上所述,代码会产生更危险的情况,因为它不检查任何格式错误的语句等。所以建议不要执行传递给您的任何字符串。也许这个网络服务只在你的局域网内部,也许你相信所有的电话都是诚实的,非破坏性的。我们可能会认为所有内部活动都很好,但是一旦员工变坏,你就会开启内部破坏的可能性。

当有人像这样呼叫您的网络服务时会发生什么:

ExecuteQuery("DELETE FROM Customers")

ExecuteQuery("UPDATE Employee SET Salary = 250000 WHERE ID= 9")

ExecuteQuery("SELECT Salary WHERE EmployeePosition = 'CEO'")

4. 为您希望图层公开的每个功能创建一个新的web方法。例如,而不是客户端调用

ExecuteQuery("SELECT ID, CustomerName FROM Customers ORDER BY CustomerName")

这样做:

public List<Customer> ListAllCustomers()

考虑创建这样的方法:

public void UpdateEmployee(Employee emp)

public void UpdateEmployeeSalary(string id, double salary) 

5. 将您的Access连接字符串放入app.config文件中。参考System.Configuration并使用ConfigurationManager。每次调用查询时加载它。这有点受到性能影响,但在更改目录路径或.mdb文件名时,维护工作量确实为零。

  private string GetConnectionString()
        {
           //do some more checking on whether the value exists as well, instead of just returning it!
            return ConfigurationManager.AppSettings["MyAccessDB"].ToString();
        }

答案 1 :(得分:0)

此外:

using (OleDbConnection conn = new OleDbConnection(
         @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + 
         @"C:\Folder\Database2.accdb;Persist Security Info=False;"))
{
    using (OleDbDataAdapter da = new OleDbDataAdapter(sqlQuery, conn))
    {
        DataSet ds = new DataSet();
        da.Fill(ds);            
        return ds;
    }
}

除非您喜欢资源泄漏,否则请执行此操作。