简体   繁体   English

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

[英]implement updateable recordsets in c#

What would it take to implement an updateable recordset in c#? 在c#中实现可更新记录集需要什么? Think what is available for Sql CE, but implemented for others like Sql Server. 想想可用于Sql CE的东西,但是为Sql Server等其他人实现了。 Do the recordset classes basically implement 99% of this and would just need some tinkering to get it added, or would this be a big undertaking? 记录集类是否基本上实现了99%,并且只需要一些修改来添加它,或者这是一项重大任务? Perhaps using some code from Mono and extending it? 也许使用Mono的一些代码并扩展它?

Just fyi, one of the early betas of .net 1.1 (if I have my versions correct) actually did implement this, but was later removed due to fear of abuse. 只是fyi,.net 1.1的早期测试版之一(如果我的版本正确)实际上确实实现了这一点,但后来由于害怕滥用而被删除。 Valid concern, but it sure would be handy in certain scenarios. 有效的担忧,但在某些情况下肯定会很方便。

There is no component available to imitate a scrollable cursor that produces and update over a live connection. 没有可用于模拟通过实时连接生成和更新的可滚动游标的组件 And for some very good reasons that are far from being abused. 并且由于一些非常好的理由远未被滥用。 Not least of which is the fact that it's a very poor use of resources on the SQL Server. 其中最重要的是它在SQL Server上使用资源非常糟糕。

Yes, the SqlDataReader does provide a fast-forward and read-only version of a query. 是的, SqlDataReader确实提供了查询的快进只读版本。 Further, the reader only retrieves one row at a time and leaves the connection open the entire time. 此外,阅读器一次只检索一行并使连接在整个时间内保持打开状态。 This allows you to fetch through a very large result set and leave the resources on the SQL Server, and you can do it very quickly. 这允许您获取非常大的结果集并将资源保留在SQL Server上,并且您可以非常快速地完成。

However, the process of making that a live feed back to the SQL Server can be simulated pretty easily. 但是,可以非常轻松地模拟将实时反馈回SQL Server的过程。 And to do this I'm going to recommend Dapper , for two reasons: 要做到这一点,我将推荐Dapper ,原因有两个:

  1. It's performance is unrivaled. 它的表现无与伦比。
  2. It's very light weight and easy to use. 它重量轻,易于使用。

Let's keep it simple first... 让我们先保持简单......

First let's start with a very simple example, so let's assume I have a table: 首先让我们从一个非常简单的例子开始,让我们假设我有一个表:

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

so now let's get some data from Foo , but before we can we need a simple model to put it into: 所以现在让我们从Foo获取一些数据,但在我们可以之前,我们需要一个简单的模型来将其放入:

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

and now we just need to get some data: 现在我们只需要获取一些数据:

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
}

Now let's update the data yeah? 现在让我们更新数据是啊?

Alright, so now that we know how to get data using Dapper, let's see how we might simulate a live stream to the database yeah? 好了,现在我们知道如何使用Dapper 获取数据,让我们看看我们如何模拟数据库的实时流是的? So first let's build a base class: 首先让我们构建一个基类:

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

so now we need to modify the Foo class just a tidge: 所以现在我们需要修改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);
        }
    }
}

so now when we update an editable property while iterating we are sending back commands to make this a 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
}

now, let's take this one step further, and let's assume that the result set you're getting back is massive , and when I say that I mean 100's of MB. 现在,让我们更进一步,让我们假设你回来的结果集是巨大的 ,当我说我的意思是100的MB。 Well, Dapper can handle that too, simply change the line that gets data from: 好吧,Dapper也可以处理它,只需更改从以下位置获取数据的行:

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

to: 至:

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

but nothing else changes! 但没有别的变化!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM