存储FileInfo实体时,SisoDB的StackOverflow异常

时间:2012-07-17 12:12:40

标签: c# nosql document-database sisodb

这个问题涉及SisoDB - 一个用C#编写的基于SQL Server的文档数据库。

我正在尝试将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);

这会导致StackOverflow异常。任何想法为什么会这样,我怎么能克服这个问题?

1 个答案:

答案 0 :(得分:4)

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"};

b)或者您可以FileData换一个FileInfo

c)或者您可以制作包装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; }
}