views:

363

answers:

3

I need some expert advice on strong typed data sets in ADO.NET that are generated by the Visual Studio. Here are the details. Thank you in advance.

  • I want to write a N-tier application where Presentation layer is in C#/windows forms, Business Layer is a Web service and Data Access Layer is SQL db.

  • So, I used Visual Studio 2005 for this and created 3 projects in a solution.

  • project 1 is the Data access layer. In this I have used visual studio data set generator to create a strong typed data set and table adapter (to test I created this on the customers table in northwind). The data set is called NorthWindDataSet and the table inside is CustomersTable.

  • project 2 has the web service which exposes only 1 method which is GetCustomersDataSet. This uses the project1 library's table adapter to fill the data set and return it to the caller. To be able to use the NorthWindDataSet and table adapter, I added a reference to the project 1.

  • project 3 is a win forms app and this uses the web service as a reference and calls that service to get the data set.

In the process of building this application, in the PL, I added a reference to the DataSet generated above in the project 1 and in form's load I call the web service and assign the received DataSet from the web service to this dataset. But I get the error:

Cannot implicitly convert type 'PL.WebServiceLayerReference.NorthwindDataSet' to 'BL.NorthwindDataSet' e:\My Documents\Visual Studio 2008\Projects\DataSetWebServiceExample\PL\Form1.cs

Both the data sets are same but because I added references from different locations, I am getting the above error I think.

So, what I did was I added a reference to project 1 (which defines the data set) to project 3 (the UI) and used the web service to get the DataSet and assing to the right type, now when the project 3 (which has the web form) runs, I get the below runtime exception.

System.InvalidOperationException: There is an error in XML document (1, 5058). ---> System.Xml.Schema.XmlSchemaException: Multiple definition of element 'http://tempuri.org/NorthwindDataSet.xsd:Customers' causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence.

I think this might be because of some cross referenceing errors.

My question is, is there a way to use the visual studio generated DataSets in such a way that I can use the same DataSet in all layers (for reuse) but separate the Table Adapter logic to the Data Access Layer so that the front end is abstracted from all this by the web service?

If I have hand write the code I loose the goodness the data set generator gives and also if there are columns added later I need to add it by hand etc so I want to use the visual studio wizard as much as possible.

+2  A: 

I would stay away from datasets if I were you. They are very much a .NET 2.0 solution to the problem, and they weren't a very good solution, either.

I would use Entity Framework as a data layer - they do not have the issues a DataSet has, including the one you're seeing. A DataSet has to live in both worlds - both XML and relational, and they don't always fit. Entity Framework can build you entity models that need only conform to standard programming concepts like inheritance and association.

Entity Framework also has fewer issues when transferred over web services. You should use WCF for all your new web service work (Microsoft now considers ASMX web services to be "legacy technology"), but even with ASMX web services, EF entities will transfer fairly cleanly. There are some relatively minor issues in .NET 3.5, but those are addressed in .NET 4.0.

John Saunders
A: 

I'd back up John here, we use EF v1.0 in N-tiered app and of course it has it's own problems but you get regular objects which you can push through service. However I'd advise ( in case you go with EF1 not EF4 which has ability to expose it's objects as POCO's) to have a separate layer of DTO objects which would me mapped to DO objects from you DAL, and use DTO for transfering through service. Also consider using .NET RIA services, they are really fantastic

@sb: on DTO, on EF, quick overlook of RIA services, old article on DTO with datasets, what you are trying to do.

vittore
Thank you. Where can I learn more about the topics you mentioned above? Also,this is a legacy project so pointer to move existing code (big code base) to new paradigm might help but I might not have a lot of flexibility on moving though...
sb
I added links to my comment
vittore
thank you for your pointers!
sb
A: 

My question is, is there a way to use the visual studio generated DataSets in such a way that I can use the same DataSet in all layers (for reuse) but separate the Table Adapter logic to the Data Access Layer so that the front end is abstracted from all this by the web service

If you don't want to rewrite your app for EF or add DTOs, and you know the schemas are equal, you could set the data set schema in your presentation layer via the web service.

Project3DataSet.ReadXmlSchema(  
    new StringReader(Project2WebService.GetCustomersDataSetSchema()));

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

Your data set schema acts as the object model. Not pretty but should do the job.

With that being said, if this is a new project, I agree with the other answers - avoid data sets.

Si
Thank you. This will surely help me since this is a legacy code base which I might not be able to move to EF. There is a LOT of code existing already. Thank you again.
sb