我正在就这个问题提出建议:
EF6 code first: How to load DbCompiledModel from EDMX file on startup?
我想将DbCompiledModel序列化为磁盘,因此我可以稍后对其进行反序列化并缩短启动时间。它需要序列化属性和字段,包括私有属性。
由于以下原因,我下面的三次尝试都失败了。我怎么能序列化DbCompiledModel的私人内容?
我通过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();
因以下原因失败:
Type 'System.Data.Entity.Infrastructure.DbCompiledModel' in Assembly 'EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
我第二次尝试通过Json使用自定义合约解析程序来包含私有字段:
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;
}
}
因以下原因失败:
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中的ReferenceLoopHandling和PreserveReferencesHandling设置:
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);
由于StackOverflowException而失败。