StackOverflow exception with SisoDB while storing a FileInfo entity
-
21-06-2021 - |
سؤال
This questions refers to the SisoDB - an SQL-Server-based document database written in C#.
I am trying to store a FileInfo entity to the database. In order to avoid (potential) circular references I define the interface for the fields I need:
interface IFileData
{
Guid Id { get; set; }
string DirectoryName { get; set; }
long Length { get; set; }
string Name { get; set; }
}
and then try to store a FileInfo entity:
var db = @"Data Source=C:\Temp\sisotest.sdf".CreateSqlCe4Db();
db.EnsureNewDatabase();
var info = new FileInfo(@"c:\config.sys");
db.UseOnceTo().InsertAs<IFileData>(info);
This results in StackOverflow exception. Any ideas why it is so and how can I overcome this problem?
المحلول
SisoDb relies on the performant and outstanding serialization framework of ServiceStack.Text and my first test was to see if it can serialize a FileInfo
, and that's where the StackOverFlowException
seems to be generated. You can try this by either using SisoDb.Serialization
(which is a copy of ServiceStack.Text) or by using ServiceStack.Text directly.
var json = info.ToJson();
As of now InsertAs<T>
requires T
to be an interface. Insert<T>
and InsertMany<T>
can handle interfaces, but also requires the actual item to implement the interface.
So as of now, to get further:
1) make a class out of 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) Normally that should have been ok, but since the FileInfo
can't be serialized to JSON, you need to, either:
a) Tell the ServiceStack serializer (contained in SisoDb.Serialization) not to include the properties causing the deserialization issue:
JsConfig<FileInfo>.ExcludePropertyNames = new[]{"Directory"};
b) Or you can make FileData
wrap a FileInfo
c) Or you can make a custom wrapper FileInfo2
which wraps 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; }
}