C# SQLite连接策略

C# SQLite连接策略,c#,database,sqlite,nhibernate,connection-string,C#,Database,Sqlite,Nhibernate,Connection String,我有一个数据库,可能在网络驱动器上。 我想实现两件事: 当第一个用户以只读模式连接到它时(他没有 具有对该位置的读写访问权限,或数据库已损坏 只读),其他用户也必须使用只读连接(甚至 如果他们有RW访问权限) 当第一个用户以RW模式连接到它时,其他用户不能 连接到数据库 我使用的是SQLite,并发性不应该是问题所在,因为数据库不应该被超过10个人同时使用 更新:这是一个我正在尝试使用的示例,因此我可以在程序本身中实现它。几乎一切都可以改变 更新:现在,当我终于理解@CL.告诉我的内容时,我让它

我有一个数据库,可能在网络驱动器上。 我想实现两件事:

  • 当第一个用户以只读模式连接到它时(他没有 具有对该位置的读写访问权限,或数据库已损坏 只读),其他用户也必须使用只读连接(甚至 如果他们有RW访问权限)
  • 当第一个用户以RW模式连接到它时,其他用户不能 连接到数据库
  • 我使用的是SQLite,并发性不应该是问题所在,因为数据库不应该被超过10个人同时使用

    更新:这是一个我正在尝试使用的示例,因此我可以在程序本身中实现它。几乎一切都可以改变

    更新:现在,当我终于理解@CL.告诉我的内容时,我让它工作了,这是更新后的代码

    using System.Diagnostics;
    using System.Linq;
    using System.IO;
    using DbSample.Domain;
    using DbSample.Infrastructure;
    using NHibernate.Linq;
    using NHibernate.Util;
    
    
    namespace DbSample.Console
    {
        class Program
        {
            static void Main(string[] args)
            {
                IDatabaseContext databaseContext = null;
    
                databaseContext = new SqliteDatabaseContext(args[1]);
    
            var connection = LockDB(args[1]);
            if (connection == null) return;
    
            var sessionFactory = databaseContext.CreateSessionFactory();
            if (sessionFactory != null)
            {
    
                int insertCount = 0;
    
                while (true) 
                {
    
                    try
                    {
    
                        using (var session = sessionFactory.OpenSession(connection))
                        {
                            string result;
                            session.FlushMode = NHibernate.FlushMode.Never;
    
                            var command = session.Connection.CreateCommand();
    
                            command.CommandText = "PRAGMA locking_mode=EXCLUSIVE";
                            command.ExecuteNonQuery();
    
    
                            using (var transaction = session.BeginTransaction(ReadCommited))
                            {
                                bool update = false;
                                bool delete = false;
                                bool read = false;
                                bool readall = false;
                                int op = 0;
                                System.Console.Write("\nMenu of the day:\n1: update\n2: delete\n3: read\n4: read all\n0: EXIT\n\nYour choice: ");
                                op = System.Convert.ToInt32(System.Console.ReadLine());
                                if (op == 1)
                                    update = true;
                                else if (op == 2)
                                    delete = true;
                                else if (op == 3)
                                    read = true;
                                else if (op == 4)
                                    readall = true;
                                else if (op == 0)
                                    break;
                                else System.Console.WriteLine("Are you retarded? Can't you read?");
    
    
    
    
                                if (delete)
                                {
                                    System.Console.Write("Enter the ID of the object to delete: ");
                                    var objectToRemove = session.Get<MyObject>(System.Convert.ToInt32(System.Console.ReadLine()));
    
                                    if (!(objectToRemove == null))
                                    {
                                        session.Delete(objectToRemove);
                                        System.Console.WriteLine("Deleted {0}, ID: {1}", objectToRemove.MyName, objectToRemove.Id);
                                        deleteCount++;
                                    }
                                    else
                                        System.Console.WriteLine("\nObject not present in the database!\n");
    
    
                                }
    
                                else if (update)
                                {
                                    System.Console.Write("How many objects to add/update? ");
                                    int number = System.Convert.ToInt32(System.Console.ReadLine());
                                    number += insertCount;
                                    for (; insertCount < number; insertCount++)
                                    {
    
                                        var myObject = session.Get<MyObject>(insertCount + 1);
    
                                        if (myObject == null)
                                        {
                                            myObject = new MyObject
                                                {
                                                    MtName = "Object" + insertCount,
                                                    IdLegacy = 0,
                                                                                               };
                                            session.Save(myObject);
                                            System.Console.WriteLine("Added {0}, ID: {1}", myObject.MyName, myObject.Id);
                                        }
                                        else
                                        {
                                            session.Update(myObject);
                                            System.Console.WriteLine("Updated {0}, ID: {1}", myObject.MyName, myObject.Id);
                                        }
                                    }
    
                                }
    
                                else if (read)
                                {
    
                                    System.Console.Write("Enter the ID of the object to read: ");
                                    var objectToRead = session.Get<MyObject>(System.Convert.ToInt32(System.Console.ReadLine()));
                                    if (!(objectToRead == null))
                                        System.Console.WriteLine("Got {0}, ID: {1}", objectToRead.MyName, objectToRead.Id);
                                    else
                                        System.Console.WriteLine("\nObject not present in the database!\n");
    
                                }
    
                                else if (readall)
                                {
    
                                    System.Console.Write("How many objects to read? ");
                                    int number = System.Convert.ToInt32(System.Console.ReadLine());
                                    for (int i = 0; i < number; i++)
                                    {
                                        var objectToRead = session.Get<MyObject>(i + 1);
                                        if (!(objectToRead == null))
                                            System.Console.WriteLine("Got {0}, ID: {1}", objectToRead.MyName, objectToRead.Id);
                                        else
                                            System.Console.WriteLine("\nObject not present in the database! ID: {0}\n", i + 1);
    
    
                                    }
    
                                }
                                update = false;
                                delete = false;
                                read = false;
                                readall = false;
    
                                transaction.Commit();
                            }
                        }    
                    }
                    catch (System.Exception e)
                    {
                        throw e;
                    }
    
    
                }
                sessionFactory.Close();
            }
    
        }
    
        private static SQLiteConnection LockDbNew(string database)
        {
            var fi = new FileInfo(database);
            if (!fi.Exists)
                return null;
            var builder = new SQLiteConnectionStringBuilder { DefaultTimeout = 1, DataSource = fi.FullName, Version = 3 };
    
            var connectionStr = builder.ToString();
            var connection = new SQLiteConnection(connectionStr) { DefaultTimeout = 1 };
            var cmd = new SQLiteCommand(connection);
    
            connection.Open();
    
            // try to get an exclusive lock on the database
            try
            {
                cmd.CommandText = "PRAGMA locking_mode = EXCLUSIVE; BEGIN EXCLUSIVE; COMMIT;";
                cmd.ExecuteNonQuery();
            }
            // if we can't get the exclusive lock, it could mean 3 things
            // 1: someone else has locked the database
            // 2: we don't have a write acces to the database location
            // 3: database itself is a read-only file
            // So, we try to connect as read-only
            catch (Exception)
            {
                // we try to set the SHARED lock
                try
                {
                    // first we clear the locks
                    cmd.CommandText = "PRAGMA locking_mode = NORMAL";
                    cmd.ExecuteNonQuery();
                    cmd.CommandText = "SELECT COUNT(*) FROM MyObject";
                    cmd.ExecuteNonQuery();
    
                    // then set the SHARED lock on the database
                    cmd.CommandText = "PRAGMA locking_mode = EXCLUSIVE";
                    cmd.ExecuteNonQuery();
                    cmd.CommandText = "SELECT COUNT(*) FROM MyObject";
                    cmd.ExecuteNonQuery();
    
                    readOnly = true;
                }
                catch (Exception)
                {
                    // if we can't set EXCLUSIVE nor SHARED lock, someone else has opened the DB in read-write mode and we can't connect at all
                    connection.Close();
                    return null;
                }
    
            } 
            return connection;
        }
    
     }
    
    使用系统诊断;
    使用System.Linq;
    使用System.IO;
    使用DbSample.Domain;
    使用DbSample.Infrastructure;
    使用NHibernate.Linq;
    使用NHibernate.Util;
    命名空间DbSample.Console
    {
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    IDatabaseContext databaseContext=null;
    databaseContext=新的SqliteDatabaseContext(args[1]);
    var连接=LockDB(参数[1]);
    if(connection==null)返回;
    var sessionFactory=databaseContext.CreateSessionFactory();
    if(sessionFactory!=null)
    {
    int insertCount=0;
    while(true)
    {
    尝试
    {
    使用(var session=sessionFactory.OpenSession(连接))
    {
    字符串结果;
    session.FlushMode=NHibernate.FlushMode.Never;
    var command=session.Connection.CreateCommand();
    command.CommandText=“PRAGMA locking\u mode=EXCLUSIVE”;
    command.ExecuteNonQuery();
    使用(var事务=session.BeginTransaction(readcommitted))
    {
    bool update=false;
    bool delete=false;
    bool read=false;
    bool readall=false;
    int op=0;
    System.Console.Write(“\n当日菜单:\n1:update\n2:delete\n3:read\n4:read all\n0:EXIT\n\n您的选择:”);
    op=System.Convert.ToInt32(System.Console.ReadLine());
    如果(op==1)
    更新=真;
    else if(op==2)
    删除=真;
    否则如果(op==3)
    读=真;
    否则如果(op==4)
    readall=true;
    否则如果(op==0)
    打破
    else System.Console.WriteLine(“你是弱智吗?你不会阅读吗?”);
    如果(删除)
    {
    System.Console.Write(“输入要删除的对象的ID:”);
    var objectToRemove=session.Get(System.Convert.ToInt32(System.Console.ReadLine());
    如果(!(objectToRemove==null))
    {
    删除(objectToRemove);
    System.Console.WriteLine(“已删除{0},ID:{1}”,objectToRemove.MyName,objectToRemove.ID);
    deleteCount++;
    }
    其他的
    System.Console.WriteLine(“\n数据库中不存在对象!\n”);
    }
    否则如果(更新)
    {
    System.Console.Write(“要添加/更新多少对象?”);
    int number=System.Convert.ToInt32(System.Console.ReadLine());
    数字+=插入计数;
    对于(;insertCount