How can I serialize a DbCompiledModel from EF6?

女生的网名这么多〃 提交于 2019-12-10 18:13:57

问题


I'm pursuing a suggestion made on this question:

EF6 code first: How to load DbCompiledModel from EDMX file on startup?

I want to serialize a DbCompiledModel to disk, so I can deserialize it later and improve startup time. It needs to serialize properties and fields including private ones.

My three attempts below have failed for the following reasons. How else could I serialize the private contents of DbCompiledModel?

BinaryFormatter

My first attempt via BinaryFormatter:

var compiledModel = modelBuilder.Build(new DbProviderInfo("System.Data.SqlClient", "2012")).Compile();
var bf = new BinaryFormatter();
var fs = new FileStream("C:\\temp\\bf.txt", FileMode.Create);
bf.Serialize(fs, compiledModel);
fs.Close();

Fails due to:

Type 'System.Data.Entity.Infrastructure.DbCompiledModel' in Assembly 'EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.

Json #1

My second attempt via Json with a custom contract resolver to include private fields:

var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver()};
var json = JsonConvert.SerializeObject(compiledModel, settings);
System.IO.File.WriteAllText("C:\\temp\\json.json", json);

...
    private class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
    {
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            var props = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                            .Select(p => base.CreateProperty(p, memberSerialization))
                        .Union(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                                   .Select(f => base.CreateProperty(f, memberSerialization)))
                        .ToList();
            props.ForEach(p => { p.Writable = true; p.Readable = true; });
            return props;
        }
    }

Fails due to:

Self referencing loop detected for property 'ProviderManifest' with type 'System.Data.Entity.Core.Metadata.Edm.Provider.EdmProviderManifest'. Path '_workspace._metadataWorkspace._itemsCSpace.ValueForDebugDisplay[0].ProviderManifest._facetDescriptions.['Edm.String'][0].FacetType'.

Json #2

And my third attempt tweaking the ReferenceLoopHandling and PreserveReferencesHandling settings in Json:

var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore};
//OR SETTINGS:
var settings = new JsonSerializerSettings() { ContractResolver = new MyContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore, PreserveReferencesHandling = PreserveReferencesHandling.Objects };
var json = JsonConvert.SerializeObject(compiledModel, settings);
System.IO.File.WriteAllText("C:\\temp\\json.json", json);

Fail due to StackOverflowException.

来源:https://stackoverflow.com/questions/32109897/how-can-i-serialize-a-dbcompiledmodel-from-ef6

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!