强类型数据行是否值得?

时间:2011-02-11 20:43:03

标签: c# datarow

我有一个数据行,我会传递并执行操作,并且希望强类型,但不需要强烈地键入表本身。

是否有工具可以使用isnull方法自动生成强类型行?

2 个答案:

答案 0 :(得分:1)

在我看来,为ADO数据类型创建一个强类型类是值得的。有两种方法可以做到这一点:

  1. 手动编码DataRow的子类或封装所需行为的任​​何内容。
  2. 编写数据的XSD文件,让Visual Studio构建强类型类。
  3. 第一种方法的优点是它提供了一个自定义API,可以完全展示您想要的内容。第二种方法通常更快。

答案 1 :(得分:0)

这是值得的,因为您可以使用强类型DataRow / DataSet进行编译时检查。

下面的代码(只是一个示例)展示了我是如何做到的。我有一个工具,可以从数据库信息中生成所有类,特别是存储过程的输出。所以我有一个存储过程返回一个结果集,其字段映射到下面的PostDtw类的属性。

该工具(包含来源)可在我的博客上找到。它还以类似的方式生成DataReader包装器。你可以从这里获得这个工具 Data Access Layer CodeGen

下面的“主要”方法显示了如何使用该类。请注意,在foreach循环中,您是如何访问类的属性,但在幕后属性getter正在使用DataRow。

方法“GetPosts1”和“GetPosts2”显示了你基本上如何使用DataTable但将其“转换”为

IEnumerable<PostDtw>

。 GetPosts1本质上使用相同的实例,而GetPosts2为每一行创建一个新实例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication5
{
  class Program
  {
    static void Main(string[] args)
    {
      var posts = GetPosts1();
      foreach (var post in posts)
      {
        Console.WriteLine(post.PostId);
        Console.WriteLine(post.PostTitle);
        Console.WriteLine(post.PostSlug);
        Console.WriteLine(post.PostDate);
      }
    }

    static IEnumerable<PostDtw> GetPosts1()
    {
      DataTable postsDt = GetPostsDataTable();
      PostDtw postDtw = new PostDtw();

      foreach(DataRow row in postsDt.Rows)
      {
        postDtw.DataRow = row;
        yield return postDtw;
      }        
    }

    static IEnumerable<PostDtw> GetPosts2()
    {
      DataTable postsDt = GetPostsDataTable();
      foreach (DataRow row in postsDt.Rows)
        yield return new PostDtw(row);
    }

    static DataTable GetPostsDataTable()
    {
      throw new NotImplementedException();
    }
  }

  /// <summary>
  ///This is the Base Class for all DataTable Wrappers
  /// </summary>
  public class BaseDataTableWrapper
  {
    public DataRow DataRow { get; set; }

    public BaseDataTableWrapper()
    {
    }

    public BaseDataTableWrapper(DataRow row)
      : this()
    {
      DataRow = row;
    }
  }

  #region [GetPost]

  /// <summary>
  ///This class is a wrapper around a DataTable,
  ///Associated with the stored procedure - GetPost
  ///This class provides a strongly typed interface to access data from the DataTable
  ///containing the result of the given stored procedure.
  /// </summary>
  public sealed class PostDtw : BaseDataTableWrapper
  {
    public Int32 PostId { get { return (Int32)DataRow[0]; } set { DataRow[0] = value; } }
    public DateTime PostDate { get { return (DateTime)DataRow[1]; } set { DataRow[1] = value; } }
    public String PostSlug { get { return (String)DataRow[2]; } set { DataRow[2] = value; } }
    public Int32 UserId { get { return (Int32)DataRow[3]; } set { DataRow[3] = value; } }
    public String PostTitle { get { return (String)DataRow[4]; } set { DataRow[4] = value; } }
    public String PostText { get { return (String)DataRow[5]; } set { DataRow[5] = value; } }
    public Boolean PostIsPublished { get { return (Boolean)DataRow[6]; } set { DataRow[6] = value; } }
    public Boolean PostIsPublic { get { return (Boolean)DataRow[7]; } set { DataRow[7] = value; } }
    public String PostTitleImg { get { if (DataRow[8] != DBNull.Value) return (String)DataRow[8]; else return default(String); } set { DataRow[8] = value; } }

    public PostDtw()
      : base()
    {
    }

    public PostDtw(DataRow row)
      : base(row)
    {
    }
  }

  #endregion [GetPost]

}