手工制作的强类型数据表ADO.net - 它可以更干净? [英] Handcrafted Strongly Typed ADO.net DataTable - Can it be cleaner?
问题描述
我最近碰到一个非常简单的类型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屋!