在c#中实现可更新的记录集

时间:2012-07-13 22:03:35

标签: c# sql sql-server ado.net recordset

在c#中实现可更新记录集需要什么?想想可用于Sql CE的东西,但是为Sql Server等其他人实现了。记录集类是否基本上实现了99%,并且只需要一些修改来添加它,或者这是一项重大任务?也许使用Mono的一些代码并扩展它?

只是fyi,.net 1.1的早期测试版之一(如果我的版本正确)实际上确实实现了这一点,但后来由于害怕被滥用而被删除。有效的担忧,但在某些情况下肯定会很方便。

1 个答案:

答案 0 :(得分:2)

没有可用于模仿可滚动游标的组件,该游标通过实时连接生成和更新。并且出于一些非常好的理由,这些原因远未被滥用。其中最重要的是,它在SQL Server上的资源使用率很低 。

是的,SqlDataReader确实提供了快进只读版本的查询。此外,阅读器一次只检索一行并使连接在整个时间内保持打开状态。这允许您获取非常大的结果集并将资源保留在SQL Server上,并且您可以非常快速地完成。

但是,可以非常轻松地模拟将 live 反馈给SQL Server的过程。要做到这一点,我将推荐Dapper,原因有两个:

  1. 它的表现无与伦比。
  2. 非常 重量轻且易于使用。
  3. 让我们先保持简单......

    首先让我们从一个非常简单的例子开始,让我们假设我有一个表:

    CREATE TABLE Foo (
        ID INT PRIMARY KEY IDENTITY(1, 1),
        Field1 FLOAT,
        Field2 VARCHAR(50)
    )
    

    所以现在让我们从Foo获取一些数据,但在我们需要一个简单的模型之前,我们需要这样做:

    public class Foo
    {
        public int ID { get; set; }
        public float Field1 { get; set; }
        public string Field2 { get; set; }
    }
    

    现在我们只需要获取一些数据:

    using Dapper;
    
    ...
    
    public void ReadFoo()
    {
        IDbConnection conn = new SqlConnection("[some connection string]");
        conn.Open();
        var list = conn.Query<Foo>("SELECT * FROM Foo");
    
        // and now you have a list of Foo objects you can iterate against
    }
    

    现在让我们更新数据是吗?

    好了,现在我们知道如何使用Dapper 获取 数据,让我们看看我们如何模拟数据库的实时流是吗?首先让我们构建一个基类:

    public class DapperModelBase
    {
        public abstract string PKField { get; }
    
        protected void OnPropertyValueChanged(string propertyName, object val)
        {
            var sql = string.Format("update {0} set {1} = @value where {2} = @id",
                this.GetType().Name,
                propertyName,
                this.PKField);
    
            IDbConnection conn = new SqlConnection("[some connection string]");
            conn.Execute(sql, new
                {
                    value = val,
                    id = this.GetType().GetProperty(this.PKField).GetValue(this, null)
                });
        }
    }
    

    所以现在我们需要修改Foo类只是一个tidge:

    public class Foo
    {
        // implement the abstract property
        public string PKField { get { return "ID"; } }
        public int ID { get; set; }
    
        private float _field1;
        public float Field1
        {
            get { return _field1; }
            set
            {
                _field1 = value;
                OnPropertyValueChanged("Field1", value);
            }
        }
    
        private string _field2;
        public string Field2
        {
            get { return _field2; }
            set
            {
                _field2 = value;
                OnPropertyValueChanged("Field2", value);
            }
        }
    }
    

    所以现在当我们在迭代时更新可编辑属性时,我们发送回命令以使其成为 live Feed:

    // and now you have a list of Foo objects you can iterate against
    foreach (var foo in list)
    {
        ...
        ...
        foo.Field1 = 123f; // sends an update
        ...
        ...
        foo.Field2 = "Hello World!" // sends an update
    }
    

    现在,让我们更进一步,让我们假设您回来的结果集 大量 ,当我说我的意思是 100的MB。 好吧,Dapper也可以处理它,只需更改从中获取数据的行:

    var list = conn.Query<Foo>("SELECT * FROM Foo");
    

    为:

    var list = conn.Query<Foo>("SELECT * FROM Foo", buffered: false);
    

    但没有其他改变!