手工制作的强类型数据表ADO.net - 它可以更干净? [英] Handcrafted Strongly Typed ADO.net DataTable - Can it be cleaner?

查看:229
本文介绍了手工制作的强类型数据表ADO.net - 它可以更干净?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近碰到一个非常简单的类型DataTable(不使用.XSD)(我已经失去了作者的网址,所以我不能归功于他),但它看起来像有很多重复的代码(如添加/删除/ GetNewRow方法)。



我试图重复的方法推入一个超类,但我由于员工需要是通用的问题。我希望能得到计算器集体蜂群思维提出了一些想法,打扫一下吗? (?如果它甚至有可能的话)

 使用系统; 
使用System.Data这; System.Collections中使用
;
使用System.Data.SqlClient的;

命名空间TypedDataSet {

公共类员工:数据表{
保护的SqlDataAdapter _adapter;

公务员(){
字符串的connectionString = TypedDataSet.Properties.Settings.Default.ConnectionString;
_adapter =新System.Data.SqlClient.SqlDataAdapter(选择编号,名字,姓氏FROM雇员,的connectionString);
_adapter.Fill(本);
}

公务员这个[INT指数] {
{返回(员工)行[指数] }
}

公共无效添加(员工行){
Rows.Add(行);
}

公共无效删除(员工行){
Rows.Remove(行);
}

公务员GetNewRow(){
员工排=(雇员)NEWROW();
返回行;
}

保护覆盖的DataRow NewRowFromBuilder(DataRowBuilder建设者){
返回新员工(制造商);
}

公众的IEnumerator的GetEnumerator(){
返回Rows.GetEnumerator();
}

保护覆盖类型GetRowType(){
返回的typeof(员工);
}
}

公共类员工:DataRow的{
内部员工(DataRowBuilder建设者)
:基地(制造商){
}

酒店的公共Int64的标识{
{返回(Int64的)基地[ID]; }
集合{基地[ID] =值; }
}

公共字符串名字{
{返回(串)基地[名字]; }
集合{基地[名字] =值; }
}

公共字符串姓氏{
{返回(串)基地[姓]; }
集合{基地[姓] =值; }
}
}
}


解决方案

我相信我已经回答了我的问题,就是那种。我不得不使用.NET 4.0来获取我所期待的specificially的动态的类型。



所以改变现有的类结果在这个问题:



Employee.cs

 使用系统; 
使用System.Data这; System.Collections中使用
;
使用System.Data.Common;

命名空间TypedDataSet {

公共类员工:BaseModel<员工> {

公职人员(布尔LOADALL){
DbDataAdapter的适配器= base.Adapter(SELECT * FROM雇员);
adapter.Fill(本);
}

保护覆盖的DataRow NewRowFromBuilder(DataRowBuilder建设者){
返回新员工(制造商);
}
}

公共类员工:DataRow的{
内部员工(DataRowBuilder建设者)
:基地(制造商){
}

酒店的公共Int64的标识{
{返回(Int64的)基地[ID]; }
集合{基地[ID] =值; }
}

公共字符串名字{
{返回(串)基地[名字]; }
集合{基地[名字] =值; }
}

公共字符串姓氏{
{返回(串)基地[姓]; }
集合{基地[姓] =值; }
}
}
}






而现在引进BaseModel,上面的类继承






BaseModel.cs

 使用系统; 
使用System.Data这; System.Collections中使用
;
使用System.Data.Common;
使用System.Data.SqlClient的;

命名空间TypedDataSet {

公共类BaseModel< T> :数据表{
保护DbDataAdapter的_adapter;
保护串_connectionString = TypedDataSet.Properties.Settings.Default.ConnectionString;

公共BaseModel(){
}

保护DbDataAdapter的适配器(SQL字符串){
_adapter =新System.Data.SqlClient.SqlDataAdapter(SQL ,_connectionString);
SqlCommandBuilder CB =新SqlCommandBuilder((SqlDataAdapter的)_adapter);
返回_adapter;
}

公共动态此[INT指数] {
{返回行[指数] }
}

公共无效添加(动态行){
Rows.Add(行);
}

公共无效删除(动态行){
Rows.Remove(行);
}

公共无效保存(){
_adapter.Update(本);
this.AcceptChanges();
}

公共动态GetNewRow(){
动态记录=(动态)NEWROW();
返回行;
}

公众的IEnumerator的GetEnumerator(){
返回Rows.GetEnumerator();
}

保护覆盖类型GetRowType(){
返回的typeof(T);
}
}
}






这让我用下面的代码来使用类:




 员工员工=新员工(真); 

员工员工= employees.GetNewRow();
employee.FirstName =格雷格;
employee.Surname =Focker;
employees.Add(员工);

employees.Save();

的foreach(在员工员工发送){
Console.WriteLine(e.FirstName +''+ e.Surname);
}



我希望,如果你有兴趣发展这进一步加班,所以未来用户计算器在这个小项目看一看 http://bitbucket.org/Mozketo/typeddataset/ 我在哪里希望主办的代码。


I have recently come across a very simple Typed DataTable (without using a .XSD)(I've lost author's URL so I can't credit him) but it looks like there's a lot of duplicated code (Such as the Add/Remove/GetNewRow methods).

I've tried to push the repetitive methods into a super class, but I have issues due to the Employee needing to be generic. I was hoping to get StackOverflow's collective hive mind to suggest some ideas to clean this up? (If it's even possible at all?)

using System;
using System.Data;
using System.Collections;
using System.Data.SqlClient;

namespace TypedDataSet {

  public class Employees : DataTable {
    protected SqlDataAdapter _adapter;

    public Employees() {
      string connectionString = TypedDataSet.Properties.Settings.Default.ConnectionString;
      _adapter = new System.Data.SqlClient.SqlDataAdapter("SELECT Id, Firstname, Surname FROM Employee", connectionString);
      _adapter.Fill(this);
    }

    public Employee this[int index] {
      get { return (Employee)Rows[index]; }
    }

    public void Add(Employee row) {
      Rows.Add(row);
    }

    public void Remove(Employee row) {
      Rows.Remove(row);
    }

    public Employee GetNewRow() {
      Employee row = (Employee)NewRow();
      return row;
    }

    protected override DataRow NewRowFromBuilder(DataRowBuilder builder) {
      return new Employee(builder);
    }

    public IEnumerator GetEnumerator() {
        return Rows.GetEnumerator();
    }

    protected override Type GetRowType() {
        return typeof(Employee);
    }
  }

  public class Employee : DataRow {
    internal Employee(DataRowBuilder builder)
      : base(builder) {
    }

    public Int64 Id {
      get { return (Int64)base["Id"]; }
      set { base["Id"] = value; }
    }

    public string FirstName {
      get { return (string)base["Firstname"]; }
      set { base["Firstname"] = value; }
    }

    public string Surname {
      get { return (string)base["Surname"]; }
      set { base["Surname"] = value; }
    }
  }
}

解决方案

I believe that I've answered my question, kind of. I've had to use .net 4.0 to get the results that I was hoping for specificially the dynamic type.

So changing the existing class in the question:

Employee.cs

using System;
using System.Data;
using System.Collections;
using System.Data.Common;

namespace TypedDataSet {

  public class Employees : BaseModel<Employee> {

    public Employees(bool loadAll) {
        DbDataAdapter adapter = base.Adapter("SELECT * FROM Employees");
        adapter.Fill(this);
    }

    protected override DataRow NewRowFromBuilder(DataRowBuilder builder) {
        return new Employee(builder);
    }
  }

  public class Employee : DataRow {
    internal Employee(DataRowBuilder builder)
      : base(builder) {
    }

    public Int64 Id {
      get { return (Int64)base["Id"]; }
      set { base["Id"] = value; }
    }

    public string FirstName {
      get { return (string)base["Firstname"]; }
      set { base["Firstname"] = value; }
    }

    public string Surname {
      get { return (string)base["Surname"]; }
      set { base["Surname"] = value; }
    }
  }
}


And now introducing BaseModel that the above class inherits


BaseModel.cs

using System;
using System.Data;
using System.Collections;
using System.Data.Common;
using System.Data.SqlClient;

namespace TypedDataSet {

    public class BaseModel<T> : DataTable {
        protected DbDataAdapter _adapter;
        protected string _connectionString = TypedDataSet.Properties.Settings.Default.ConnectionString;

        public BaseModel() {
        }

        protected DbDataAdapter Adapter(string sql) {
            _adapter = new System.Data.SqlClient.SqlDataAdapter(sql, _connectionString);
            SqlCommandBuilder cb = new SqlCommandBuilder((SqlDataAdapter)_adapter);
            return _adapter; 
        }

        public dynamic this[int index] {
            get { return Rows[index]; }
        }

        public void Add(dynamic row) {
            Rows.Add(row);
        }

        public void Remove(dynamic row) {
            Rows.Remove(row);
        }

        public void Save() {
            _adapter.Update(this);
            this.AcceptChanges();
        }

        public dynamic GetNewRow() {
            dynamic row = (dynamic)NewRow();
            return row;
        }

        public IEnumerator GetEnumerator() {
            return Rows.GetEnumerator();
        }

        protected override Type GetRowType() {
            return typeof(T);
        }
    }
}


Which allows me to consume the class using the following code:


Employees employees = new Employees(true);

Employee employee = employees.GetNewRow();
employee.FirstName = "Greg";
employee.Surname = "Focker";
employees.Add(employee);

employees.Save();

foreach (Employee e in employees) {
  Console.WriteLine(e.FirstName + ' ' + e.Surname);
}

I hope to evolve this further overtime so future StackOverflow users if you're interested in this little project take a look at http://bitbucket.org/Mozketo/typeddataset/ where I hope to host the code.

这篇关于手工制作的强类型数据表ADO.net - 它可以更干净?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆