C# SQLite连接策略
我有一个数据库,可能在网络驱动器上。 我想实现两件事:C# SQLite连接策略,c#,database,sqlite,nhibernate,connection-string,C#,Database,Sqlite,Nhibernate,Connection String,我有一个数据库,可能在网络驱动器上。 我想实现两件事: 当第一个用户以只读模式连接到它时(他没有 具有对该位置的读写访问权限,或数据库已损坏 只读),其他用户也必须使用只读连接(甚至 如果他们有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