如何在.NET的N层应用程序中使用强类型数据集?

6
我需要一些关于ADO.NET中强类型数据集的专家建议,这些数据集是由Visual Studio生成的。以下是详细信息。谢谢。
  • 我想编写一个N层应用程序,其中演示层在C# / Windows表单中,业务层是Web服务,数据访问层是SQL数据库。

  • 因此,我使用Visual Studio 2005,并在解决方案中创建了3个项目。

  • 项目1是数据访问层。在这个项目中,我使用Visual Studio数据集生成器创建了一个强类型数据集和表适配器(为了测试,我在Northwind的客户表上创建了这个)。数据集被称为NorthWindDataSet,里面的表是CustomersTable。

  • 项目2有Web服务,仅公开1个方法GetCustomersDataSet。这使用项目1库的表适配器填充数据集并将其返回给调用者。为了能够使用NorthWindDataSet和表适配器,我添加了对项目1的引用。

  • 项目3是一个Windows窗体应用程序,它将Web服务作为引用,并调用该服务以获取数据集。

在构建此应用程序的过程中,在PL中,我向项目1中生成的DataSet添加了一个引用,并在表单的加载中调用Web服务,并将从Web服务接收到的DataSet分配给此数据集。但是我遇到了错误:
无法隐式转换类型“PL.WebServiceLayerReference.NorthwindDataSet”为“BL.NorthwindDataSet” e:\ My Documents \ Visual Studio 2008 \ Projects \ DataSetWebServiceExample \ PL \ Form1.cs
两个数据集相同,但由于我从不同位置添加了引用,因此我认为出现了上述错误。
因此,我添加了对项目1(定义数据集)到项目3(UI)的引用,并使用Web服务获取DataSet并将其分配给正确的类型,现在当运行项目3(具有Web表单)时,我会收到以下运行时异常。
System.InvalidOperationException: XML文档中存在错误(1, 5058)。 ---> System.Xml.Schema.XmlSchemaException: 元素 'http://tempuri.org/NorthwindDataSet.xsd:Customers' 的多个定义导致内容模型变得不明确。必须形成一个内容模型,以便在验证元素信息项序列期间,可以逐个验证该序列中的每个项所包含的直接、间接或隐式包含其内部的粒子,而不需要检查该项的内容或属性,也不需要关于其余序列中的项的任何信息。
我认为这可能是由于一些交叉引用错误造成的。
我的问题是,是否有一种方式可以使用Visual Studio生成的DataSets,在所有层中都可以使用相同的DataSet(进行重用),但将Table Adapter逻辑分离到数据访问层,以使前端通过Web服务抽象出所有这些?

如果我手写代码,就会失去数据集生成器所提供的好处,而且如果以后添加了列,我还需要手动添加等等,因此我希望尽可能多地使用Visual Studio向导。

3个回答

2
如果我是你,我会避开数据集。它们是 .NET 2.0 解决问题的方案,而且它们也不是一个很好的解决方案。
我建议使用实体框架作为数据层 - 它们没有数据集的问题,包括您正在看到的问题。数据集必须同时存在于 XML 和关系型数据库中,它们并不总是适用。实体框架可以为您构建实体模型,这些模型只需要符合标准编程概念,如继承和关联。
相对于数据集,实体框架在通过 Web 服务传输时也有较少的问题。您应该使用 WCF 来处理所有新的 Web 服务工作(Microsoft 现在认为 ASMX Web 服务是“遗留技术”),但即使是在 ASMX Web 服务中,EF 实体也会比较干净地传输。在 .NET 3.5 中存在一些相对较小的问题,但这些问题已在 .NET 4.0 中得到解决。

0
我的问题是,是否有一种方法可以使用Visual Studio生成的DataSets,以便我可以在所有层中使用相同的DataSet(以便重用),但将Table Adapter逻辑分离到数据访问层,以便前端通过Web服务抽象出所有这些内容?
如果您不想为EF重写应用程序或添加DTO,并且知道模式相等,则可以通过Web服务在表示层中设置数据集模式。
Project3DataSet.ReadXmlSchema(  
    new StringReader(Project2WebService.GetCustomersDataSetSchema()));

[WebMethod]
public string GetCustomersDataSetSchema()
{
   return new Project1DataSet().GetXmlSchema();
}

你的数据集模式充当对象模型。不太美观但应该能完成任务。

话虽如此,如果这是一个新项目,我同意其他答案 - 避免使用数据集。


谢谢。这肯定会对我有所帮助,因为这是一个遗留的代码库,我可能无法将其移动到 EF。已经存在了很多代码。再次感谢您。 - sb.

0

我支持John的观点,我们在N层应用中使用EF v1.0,当然它有自己的问题,但你可以得到常规对象,可以通过服务推送。然而,我建议(如果你选择EF1而不是具有将其对象公开为POCO的EF4)拥有一个单独的DTO对象层,这些对象将从DAL映射到DO对象,并使用DTO进行传输。另外考虑使用.NET RIA服务,它们真的很棒。

@sb:关于DTOEFRIA服务的快速概述,以及使用数据集的DTO的旧文章,这是你想要做的。


谢谢。我在哪里可以了解更多关于您上面提到的话题?另外,这是一个遗留项目,所以指针来移动现有代码(大型代码库)到新范例可能会有所帮助,但我在移动方面可能没有太多的灵活性... - sb.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接