none
Extending DataRow to implement IDataErrorInfo RRS feed

  • Question

  • Hi All,

     

    Anyone know why you can't extend the autogenerated classes created from data sources to implement IDataErrorInfo in 2005?

     

    I've read through "Data Binding with WIndows Forms 2.0" (MS .Net Dev Servies) and the book seems to assume you'll be creating an explicit layer of business objects.  This seems a pain in the *** when all that layer will be doing is passing through the data from the auto-generated data access objects.

     

    The auto-generated code provide partial class definitions for your data rows (derived from

    System.Data.DataRow) but there's a fleeting reference in the above book stating that the DataRowView class is the one to implement IDataErrorInfo in.  I added IDataErrorInfo to the DataRow class to no effect but have been unable to track down how to get hold of the DataRowView objects.

     

    Creating explicit business objects with attributes etc, makes the GUI easy to implement, but it seems to open a whole host of other problems with the synchronisation of these objects with the dataset that I would still like to interact with via the generated code.

     

    Thanks in adavnce for any input,

     

    Andy

     

     

     

    Wednesday, February 13, 2008 9:45 AM

Answers

  • Thanks Marc,

     

    I'm going to implement the validation logic in the dataset e.g. as follows:

     

    Code Snippet

    partial class IPLDataSet

    {

      partial class CarRow

      {

        public bool validate()

        {

          if (CarId > 10)

          {

            SetColumnError("CarId", "Cannot be > 10");

            RowError = "bugger!";

            return false;

          }

        return true;

        }

      }

    }

     

     

    and get the grid to call validate() within the validating event for the cell/row/grid as appropriate.   That's unless I can convince the management that moving to Studio 2008 is top idea!

     

    Thanks Andy

    Wednesday, February 13, 2008 12:55 PM

All replies

  • I believe you can use SetColumnError to indicate that it is in error (null or "" to clear).

     

    However, re DataRow vs objects - I think the assumption is that you are using *either* the DataTable approach, *or* custom objects (perhaps with ORM tools like LINQ-to-SQL, ADO.NET Entity Framework or NHibernate) - not that you would have both implementations.

     

    There is a lot of focus on the entity (business object) approach, and I 100% approve; DataTable just isn't the right road, IMO.

     

    Marc

    Wednesday, February 13, 2008 10:11 AM
  • Thanks for that Marc,

     

    How do you populate the entity/business objects?  Surely, as I'm interacting with an SQL Server db, it's best to use the DataSet/DataTable approach at that point to make it easy for the developer to generated the DAL?

     

    Thanks Andy 

    Wednesday, February 13, 2008 10:43 AM
  • LINQ-to-SQL targets SQL Server, and genrates an object layer for you - it just doesn't have anything to do with DataTable, which is looking quite aged now... don't get me wrong, it still works, but more powerful (and efficient) constructs are available.

     

    And quite frankly LINQ out-shines DataTable in most ways. I can't to justice to just how flexible LINQ queries are - but the key point is that they are composable - i.e. the query that goes down to the database is exactly what *that scenario* needs; it doesn't have to re-use something and then throw away all the columns. Only care about the customer number and name? Fine - we'll leave the other 27 columns in the database then... want page 27? fine. Want to build your complex filter for a search screen without worrying about SQL (and injection risk)? fine...

     

    All very easy, and allows you to use the sam query syntax for a whole range of scenarios.

     

    Marc

    Wednesday, February 13, 2008 10:53 AM
  • Here you go - a quick example: the complex C# code for getting the third page of a filtered set of data with a custom sort into an array of fully-populated objects:

     

    Code Snippet

    var query =

        from order in Orders

        where order.Status == OrderStatus.Open

        orderby order.Number descending

        select order;

     

    Order[] orders = query.Skip(20).Take(10).ToArray();

     

     

    The SQL that goes to the server will do all of that in a single operation. If I had done a custom select, for example just the numbers:

     

    Code Snippet

      select order.Number;

     

    then the SQL "SELECT" would only include this column (and obviously I'd need int[] orders = {blah}) - but all verified at compile-time ;-p

     

     

    Wednesday, February 13, 2008 10:58 AM
  • Thanks Marc,

     

    LINQ sounds great but I'm using C# Studio 2005 & SQL Server 2005 and the wider project will not be updating to 2008 for 6 months.

     

    So should the plan be to create business objects that for now are populated from datatables and replace that processing with a LINQ implementation later?  Any tips on synchronising the business objects with the datatables?

     

    Thank Andy

    Wednesday, February 13, 2008 11:06 AM
  • SQL Server 2005 is fine, but LINQ does favor C# 3 (VS 2008), and absolutely requires .NET 3.5

     

    Other than trivial projects, I doubt that you can easily migrate between DataTable and a business object model - most of your code will break (sometimes in subtle ways).

     

    If you currently use DataTable and are familiar with it, then I'd stick with it; but consider LINQ for the next project... of course, if the project is longer-term (and you have enough time to familiarise yourself first), I'd simply get a few VS2008 copies and run with LINQ. You could even manage (just about) with Express Edition if cost was an issue.

     

    As for sync; again LINQ would do that for us; doing it ourselves is a pain. You could consider other (2.0) tools like NHibernate, but I haven't used it [so not a recommendation].

     

    Marc

    Wednesday, February 13, 2008 11:16 AM
  • Thanks Marc,

     

    I'm going to implement the validation logic in the dataset e.g. as follows:

     

    Code Snippet

    partial class IPLDataSet

    {

      partial class CarRow

      {

        public bool validate()

        {

          if (CarId > 10)

          {

            SetColumnError("CarId", "Cannot be > 10");

            RowError = "bugger!";

            return false;

          }

        return true;

        }

      }

    }

     

     

    and get the grid to call validate() within the validating event for the cell/row/grid as appropriate.   That's unless I can convince the management that moving to Studio 2008 is top idea!

     

    Thanks Andy

    Wednesday, February 13, 2008 12:55 PM