是否在事务内部处理SQLiteConnection

本文关键字:处理 SQLiteConnection 内部 事务 是否 | 更新日期: 2023-09-27 17:49:23

这可以,但是Resharper在注释行

上显示"访问已处置的闭包"
using (var db = new SQLiteConnection(SQLitePath))
            {
                db.CreateTable<Locations>();
                db.RunInTransaction(() =>
                {
                    db.Insert(new Locations // Resharper: "Access to disposed closure" ???
                    {
                        PersonId = personId,
                        Latitude = latitude,
                        Longitude = longitude,
                        SentTimeUTC = sentTimeUTC,
                        ReceivedTimeLocal = receivedTimeLocal,
                        CivicAddress = civicAddress
                    });
                });
            }

这种替代方法也可以工作,但是与Resharper相同:

    var db = new SQLiteConnection(SQLitePath);
    {
        db.CreateTable<Locations>();
        db.RunInTransaction(() =>
        {
            db.Insert(new Locations // this works, although Resharper warns: "Access to disposed closure" ???
               {
                   PersonId = personId,
                      Latitude = latitude,
                      Longitude = longitude,
                      SentTimeUTC = sentTimeUTC,
                      ReceivedTimeLocal = ReceivedTimeLocal,
                      CivicAddress = civicAddress
               });
        });
    }
    db.Dispose();

两者都有效,所以我想这并不太重要,但是一种方法比另一种方法更好吗?有没有办法既能安抚Resharper,又能完成任务?

更新

Donal所说的似乎是合理的,但我仍然得到Resharper"潜在的代码质量问题"的警告,对于这个重构的代码,在插入语句中:

public void InsertLocationRecord(string personId, double latitude, double longitude,
    DateTime sentTimeUTC, DateTime receivedTimeLocal, string civicAddress) 
{
    Locations locs = new Locations { PersonId = personId,
                                     Latitude = latitude,
                                     Longitude = longitude,
                                     SentTimeUTC = sentTimeUTC,
                                     ReceivedTimeLocal = receivedTimeLocal,
                                     CivicAddress = civicAddress
                                   };
    using (var db = new SQLiteConnection(SQLitePath))
    {
        db.CreateTable<Locations>();
        db.RunInTransaction(() =>
                                {
                                    db.Insert(locs); // Still get, "Access to disposed closure" on this line.
                                });
    }
}

也许我重构问题的方式不对?我想这和之前的方法没有太大区别;如何确保los实例已被处理?或者这不是问题所在?

是否在事务内部处理SQLiteConnection

问题是你正在中间创建一个Locations的自定义子类,它拾取了各种它不需要作为当前上下文的一部分的东西,而ReSharper正在拾取(并且无法证明它不会以某种方式逃脱)。最简单的修复方法实际上是向Locations添加一个构造函数(或多个构造函数,如果需要的话),以允许您使用所有正确的值实例化它,而不需要闭包捕获。

第一步:假设您的Location类中有如下代码:

class Locations { 
    int PersonId;
    int Latitude;
    int Longitude;
    int SentTimeUTC;
    int ReceivedTimeLocal;
    int CivicAddress;
    // Functions;
    // {
    // Disposable resource
    // }
    public Locations (latitude,longitude,sentTimeUTC,receivedTimeLocal,civicAddress)
    {
        PersonId = personId;
        Latitude = latitude;
        Longitude = longitude;
        SentTimeUTC = sentTimeUTC;
        ReceivedTimeLocal = receivedTimeLocal;
        CivicAddress = civicAddress;
    };
};

把你的类改成一个IDisposable类,像这样

class Locations : IDisposable { 
    int PersonId;
    int Latitude;
    int Longitude;
    int SentTimeUTC;
    int ReceivedTimeLocal;
    int CivicAddress;
    // Functions;
    // {
    // Disposable resource
    // }
    public Locations (latitude,longitude,sentTimeUTC,receivedTimeLocal,civicAddress)
    {
        PersonId = personId;
        Latitude = latitude;
        Longitude = longitude;
        SentTimeUTC = sentTimeUTC;
        ReceivedTimeLocal = receivedTimeLocal;
        CivicAddress = civicAddress;
    }
    public void Dispose() {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing) {
        if (disposing) {
            // Free your disposable resources here
            base.Dispose(disposing);
        }
    }
};

步骤2:然后将调用更改为原始代码

Locations locs = new Locations { PersonId = personId,
         Latitude = latitude,
         Longitude = longitude,
         SentTimeUTC = sentTimeUTC,
         ReceivedTimeLocal = receivedTimeLocal,
         CivicAddress = civicAddress
       };
using (var db = new SQLiteConnection(SQLitePath))
{
db.CreateTable<Locations>();
db.RunInTransaction(() =>
    {
        db.Insert(locs); // Still get, "Access to disposed closure" on this line.
    });
}

using (Locations locs = new Locations { PersonId = personId,
         Latitude = latitude,
         Longitude = longitude,
         SentTimeUTC = sentTimeUTC,
         ReceivedTimeLocal = receivedTimeLocal,
         CivicAddress = civicAddress
    }) {
    using (var db = new SQLiteConnection(SQLitePath))
    {
    db.CreateTable<Locations>();
    db.RunInTransaction(() =>
        {
            db.Insert(locs); // Still get, "Access to disposed closure" on this line.
        });
    }
}