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.