【问题标题】:Class to DataSet / DataSet to class类到数据集/数据集到类
【发布时间】:2012-05-12 20:10:30
【问题描述】:

现在我正在尝试创建一个动态处理数据库的数据库处理程序。假设我有一类字段类型“String、int、bool、String”,并且想将此类转换为表格,并将所有字段类型转换为数据集的“字段”?

我该怎么做?

另外,我可以创建几个继承的类:“System.Data.DataSet”、“System.Data.DataTable”、“System.Data.DataRow”,以及某种适配器来处理它。

我知道当你进入设计模式并创建一个数据集时,当你查看代码时真的很难辨认出来。但是不应该通过使用这些对象并创建处理它们的类来动态“创建”数据库。它不会获得“设计器视图”,但 Database.AddTable(new Table("Field1", "Field2, "Field3")) 应该与您在设计器模式下以图形方式执行的操作相同。

有什么想法吗?

主要思想是它很灵活,我可以采用任何类并将其转换为行表,该类的字段值的每个对象都作为数据库字段。

更新

这只是我在过去一个小时里做的一个简单的课程,我的想法是对的吗? 仍然需要能够将 DataSet 添加到 *.mdf / *.sdf 文件,我该怎么做?

public class DataAccess
{

    SqlConnection connection;
    DataSet dataSet;

    public DataAccess(String databaseName, String connectionStr)
    {
        dataSet = new DataSet(databaseName);
        connection = new SqlConnection(connectionStr);
    }

    public void AddTable<T>(String tableName)
    {
        dataSet.Tables.Add(new DBTable<T>(tableName));
    }

    public void AddRow<T>(String tableName, T row)
    {
        ((DBTable<T>)dataSet.Tables[tableName]).AddRow<T>(row);
    }

    public List<C> GetRows<T, C>(String tableName, String columnName)
    {
        return ((DBTable<T>)dataSet.Tables[tableName]).GetRow<C>(columnName);
    }

    public String GetXML()
    {
        return dataSet.GetXml();
    }

    #region METHOD PROPERTIES

    public int ColumnCount(String tableName)
    {
        for (int i = 0; i < dataSet.Tables.Count; i++)
        {
            if (dataSet.Tables[i].TableName == tableName)
            {
                return dataSet.Tables[i].Columns.Count;
            }
        }

        return 0;
    }

    #endregion


}

public class DBTable<T> : System.Data.DataTable
{
    public DBTable(String tableName) : base(tableName)
    {

        PropertyInfo[] properties = typeof(T).GetProperties();

        for (int i = 0; i < properties.Length; i++)
        {
            try
            {
                AddColumn(properties[i].Name, properties[i].PropertyType);
            }
            catch { }
        }

    }

    private void AddColumn(String name, Type t)
    {
        this.Columns.Add(new DataColumn(name, t, null, MappingType.Attribute));
    }

    public void AddRow<T>(T obj)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();

        if (properties.Length == this.Columns.Count)
        {

            bool valid = true;

            for (int i = 0; i < properties.Length; i++)
            {
                if (properties[i].PropertyType != this.Columns[i].DataType)
                {
                    valid = false;
                }
            }

            if (valid)
            {
                object[] p = new object[this.Columns.Count];

                for (int i = 0; i < properties.Length; i++)
                {
                    p[i] = properties[i].GetValue(obj, null);
                }

                this.Rows.Add(p);
            }
        }
    }

    public List<T> GetRow<T>(String columnName)
    {

        List<T> objects = new List<T>();

        for (int i = 0; i < this.Rows.Count; i++)
        {
            objects.Add((T)this.Rows[i][this.Columns[columnName]]);
        }

        return objects;

    }
}

【问题讨论】:

  • 给这只猫剥皮的方法很多。你试过什么?
  • 我还没有尝试过任何东西,但我想因为数据库设计器所做的只是根据我以图形方式执行的操作来创建类,这意味着它应该通过添加执行此操作的处理程序来工作。当我添加一个字段表并且这些字段具有设置(PK、FK、NotNull 等)时,它必须使用类属性和属性值来创建一个包含该类的所有字段的“表”因此,添加 AddRow(T class) 应该是可能的。我错了吗?
  • 简单;一些灵活和可重复使用的东西。我可以在项目中移动。
  • 更新我添加了我的代码并尝试使用一些简单的类,它可以工作并在 GetRow 方法上返回良好的结果,我可以添加一个新类来获取它的属性然后返回正确的。不过,我还能做些什么呢?如何将 DataSet 保存到表中?以及如何管理 TableAdapter?
  • ...也许最重要的是,如何在字段/行上设置值,例如“唯一/主键/非空/最大长度”等...

标签: c# database dataset dynamically-generated


【解决方案1】:

Petapoco 库正是您所寻找的。您可以非常轻松地将数据从数据库保存和检索到 POCO 对象,反之亦然。

您可能需要了解通用列表和一些 LINQ:Petapoco 方法不使用 DataSetDataTable 对象。

正如 leppie 所说,这并不是问题的答案。因此,可以通过这种方式创建与类匹配的 DataTable 对象:

public static DataTable CreateDataTable<T>()
{
    var dt = new DataTable();

    var propList = typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

    foreach(MemberInfo info in propList)
    {
        if(info is PropertyInfo)
            dt.Columns.Add(new DataColumn(info.Name, (info as PropertyInfo).PropertyType));
        else if(info is FieldInfo)
            dt.Columns.Add(new DataColumn(info.Name, (info as FieldInfo).FieldType));
    }

    return dt;
}

如果您希望以后填写此表:

public static void FillDataTable<T>(DataTable dt, List<T> items)
{
    var propList = typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);

    foreach(T t in items)
    {
        var row = dt.NewRow();
        foreach(MemberInfo info in propList)
        {
            if (info is PropertyInfo)
                row[info.Name] = (info as PropertyInfo).GetValue(t, null);
            else if (info is FieldInfo)
                row[info.Name] = (info as FieldInfo).GetValue(t);
        }
        dt.Rows.Add(row);
    }
}

如果您希望同时创建和填充 DataTable 对象,也可以在一个函数中混合使用这两个功能。

【讨论】:

  • 我想学习如何自己实现它,而不是使用预构建库。有什么建议?不过会调查这个项目......
  • 我更新了自己的帖子,如果相似,请查看。因为我想理解和学习它而不是重复使用别人的工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多