У меня есть две программы C#, которые совместно используют единственный файл базы данных SQLite.
Одна программа (позволяют нам назвать это Устройством записи) пишет новые данные в базу данных. Другая программа (Читатель) читает его. Обе программы используют Быстрый NHibernate и Систему. Данные. SQLite для доступа к DB.
В настоящее время я только что получил большую Кнопку Обновить на своей Программе чтения, и пользователь должен нажать ее для получения любых новых данных, которые были записаны в DB начиная с последнего обновления. Это работает, но едва изящно.
Там какой-либо путь состоит в том, чтобы заставить NHibernate запускать событие в Программу чтения, когда DB обновляется Устройством записи, таким образом, я могу автоматически представить новые данные пользователю? (Я посмотрел на документы NH для Перехватчиков и Событий, но не было ясно, сделают ли они то, что я хочу),
Или, есть ли хороший способ опросить относительно обновлений с помощью NH?
При сбое решения NH, может я делать что-то похожее с Системой. Данные. SQLite, или с помощью другого более низкого механизма уровня?
Вы можете поместить System.IO.FileWatcher
в общий файл. Это скажет вам, когда он был обновлен.
Вот пример кода, который использует FileSystemWatcher, как предложил Джон Рейнер ...
// Watches for writes to database file
private static FileSystemWatcher _dbFileWatcher;
/// <summary>
/// Set up an event handler that is called when SQLite database is written to.
/// </summary>
/// <param name="onChangedHandler"></param>
public static void SetupSqliteDatabaseWatcher(FileSystemEventHandler onChangedHandler)
{
// Create a new FileSystemWatcher and set its properties.
_dbFileWatcher = new FileSystemWatcher
{
Path = "<directory containing DB file>",
Filter = "<DB file>.db",
NotifyFilter = NotifyFilters.LastWrite
};
// Add the event handler
_dbFileWatcher.Changed += onChangedHandler;
// Begin watching.
_dbFileWatcher.EnableRaisingEvents = true;
}
// Event handler
private static void OnDbWritten(object source, FileSystemEventArgs e)
{
Debug.Print("DB written");
}
// Set up the event handler
SetupSqliteDatabaseWatcher(OnDbWritten);
Я думаю, что перехватчик или событие на стороне писателя были бы правильным решением для этого. В нашем текущем проекте мы сделали нечто подобное, и он отлично работает.
Используя этот подход, вы сохраните возможность переключать базу данных ниже или сопоставление и можете разработать свое событие обновления от простого триггера TableUpdate, который, я думаю, должен быть выполнен в течение нескольких часов, до конкретного события обновления, содержащего все измененные данные.
РЕДАКТИРОВАТЬ:
Прежде всего, я бы отслеживал не только OnSave, но и AfterTransactionCompleted, чтобы гарантировать завершение транзакции. Это также позволяет вам собирать все объекты tx. Самый простой способ сделать это - переопределить объект EmptyInterceptor следующим образом:
public class EntityInterceptor : EmptyInterceptor
{
private IList<object> entities = new List<object>();
public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
{
entities.Add(entity);
return base.OnSave(entity, id, state, propertyNames, types);
}
public override void AfterTransactionCompletion(ITransaction tx)
{
if (tx.WasCommitted)
{
Console.WriteLine("Data has been inserted. Notify the reader here.");
}
entities = new List<object>();
}
}
Самым простым подходом для межпроцессного взаимодействия IMO было бы удаленное взаимодействие .net. Есть несколько примеров, как это сделать. Более простой вариант можно найти здесь . Или, если вы хотите попробовать WCF, см. здесь . Или выполните поиск SO, здесь можно найти множество хороших примеров.