Исключение Stackru с SisoDB при сохранении сущности FileInfo
Эти вопросы относятся к SisoDB - базе данных документов на основе SQL-сервера, написанной на C#.
Я пытаюсь сохранить сущность FileInfo в базе данных. Чтобы избежать (потенциальных) циклических ссылок, я определяю интерфейс для нужных мне полей:
interface IFileData
{
Guid Id { get; set; }
string DirectoryName { get; set; }
long Length { get; set; }
string Name { get; set; }
}
и затем попытайтесь сохранить сущность FileInfo:
var db = @"Data Source=C:\Temp\sisotest.sdf".CreateSqlCe4Db();
db.EnsureNewDatabase();
var info = new FileInfo(@"c:\config.sys");
db.UseOnceTo().InsertAs<IFileData>(info);
Это приводит к исключению Stackru. Есть идеи, почему это так и как я могу преодолеть эту проблему?
1 ответ
SisoDb опирается на производительную и выдающуюся инфраструктуру сериализации ServiceStack.Text, и мой первый тест состоял в том, чтобы увидеть, может ли он сериализовать FileInfo
и вот где StackOverFlowException
кажется генерируется. Вы можете попробовать это, используя SisoDb.Serialization
(который является копией ServiceStack.Text) или с помощью ServiceStack.Text напрямую.
var json = info.ToJson();
По состоянию на сейчас InsertAs<T>
требует T
быть интерфейсом. Insert<T>
а также InsertMany<T>
может обрабатывать интерфейсы, но также требует фактического элемента для реализации интерфейса.
Итак, на данный момент, чтобы получить дальше:
1) сделать класс из IFileData
,
public class FileData
{
public Guid Id { get; set; }
public string DirectoryName { get; set; }
public long Length { get; set; }
public string Name { get; set; }
}
2) Обычно это должно было быть хорошо, но так как FileInfo
не может быть сериализован в JSON, вам также нужно:
a) Сообщите сериализатору ServiceStack (содержится в SisoDb.Serialization) не включать свойства, вызывающие проблему десериализации:
JsConfig<FileInfo>.ExcludePropertyNames = new[]{"Directory"};
б) или вы можете сделать FileData
завернуть FileInfo
в) Или вы можете сделать специальную обертку FileInfo2
который оборачивает FileInfo
,
class Program
{
static void Main(string[] args)
{
var db = @"Data Source=D:\Temp\sisotest.sdf".CreateSqlCe4Db();
db.EnsureNewDatabase();
var info = new FileInfo2(@"D:\Temp\test.txt");
db.UseOnceTo().InsertAs<FileData>(info);
}
}
public class FileInfo2
{
public FileInfo2(string cConfigSys)
{
var f = new FileInfo(cConfigSys);
DirectoryName = f.DirectoryName;
Length = f.Length;
Name = f.Name;
}
public string DirectoryName { get; private set; }
public long Length { get; private set; }
public string Name { get; private set; }
}
public class FileData
{
public Guid Id { get; set; }
public string DirectoryName { get; set; }
public long Length { get; set; }
public string Name { get; set; }
}