4

在 C# 中实现可更新记录集需要什么?想想什么可用于 Sql CE,但可以为 Sql Server 等其他工具实现。记录集类是否基本上实现了 99% 的功能,并且只需要一些修补来添加它,或者这会是一项艰巨的任务吗?也许使用 Mono 的一些代码并对其进行扩展?

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

4

1 回答 1

2

没有可用于模拟通过实时连接生成和更新的可滚动游标的组件。并且出于一些非常好的理由,这些理由远没有被滥用。其中最重要的一点是它对SQL Server 上的资源的使用非常糟糕。

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

但是,可以很容易地模拟将实时反馈反馈到 SQL Server 的过程。为此,我将推荐Dapper,原因有两个:

  1. 它的性能是无与伦比的。
  2. 它重量轻,易于使用。

让我们先保持简单...

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

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类只是一个小插曲:

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);
        }
    }
}

因此,现在当我们在迭代时更新可编辑属性时,我们会发回命令以使其成为实时提要:

// 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);

但没有其他改变!

于 2013-01-10T19:26:17.787 回答