我们希望在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。
答案 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;
}
}
除非您喜欢资源泄漏,否则请执行此操作。