0

我有一个数据行,我可以传递并使用它,并且想对其进行强类型化,但不需要对表本身进行强类型化。

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

4

2 回答 2

1

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

  1. 手动编码一个子类DataRow或封装你想要的行为的任何东西。
  2. 编写数据的 XSD 文件并让 Visual Studio 构造强类型类。

第一种方法的优点是它提供了一个自定义 API,可以准确地公开您想要的内容。第二种方法通常更快。

于 2011-02-11T21:25:54.477 回答
0

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

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

该工具(带有源代码)可在我的博客上找到。它还以类似的方式生成 DataReaders 包装器。您可以从此处获取工具 Data Access Layer CodeGen

下面的“Main”方法显示了您将如何使用该类。请注意,在 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]

}
于 2011-02-12T04:30:21.823 回答