using System.Data.Entity.ModelConfiguration.Configuration;
using System.Linq;
using System.Collections.Generic;
namespace TestCase.EntityFramework
{
public class TestCaseDBConfig : DbConfiguration
{
private static string EFFoldPath = "";
public TestCaseDBConfig() : base()
{
SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
EFFoldPath = AppDomain.CurrentDomain.BaseDirectory + "App_Data\\EFCache";
if (!Directory.Exists(EFFoldPath))
Directory.CreateDirectory(EFFoldPath);
TestCaseDbModelStore cachedDbModelStore = new TestCaseDbModelStore(EFFoldPath);
IDbDependencyResolver dependencyResolver = new SingletonDependencyResolver<DbModelStore>(cachedDbModelStore);
AddDependencyResolver(dependencyResolver);
}
private class TestCaseDbModelStore : DefaultDbModelStore
{
public TestCaseDbModelStore(string location)
: base(location)
{ }
public override XDocument TryGetEdmx(Type contextType)
{
return LoadXml2(contextType, XDocument.Load);
}
private void GetConceptualAssociationNames(List<System.Data.Entity.Core.Metadata.Edm.AssociationType> lstAssociationTypes, List<string> lstNames)
{
int oldCount = lstNames.Distinct().ToList().Count;
foreach (var association in lstAssociationTypes)
{
if (association.AssociationEndMembers != null && association.AssociationEndMembers.Count > 0)
{
var isAssociaEsixt = association.AssociationEndMembers.Where(a => lstNames.Contains(a.GetEntityType().Name)).FirstOrDefault() != null;
if (isAssociaEsixt)
{
if (!lstNames.Contains(association.Name))
lstNames.Add(association.Name);
foreach (var endMember in association.AssociationEndMembers)
{
if (!lstNames.Contains(endMember.GetEntityType().Name))
lstNames.Add(endMember.GetEntityType().Name);
}
}
}
}
if (oldCount != lstNames.Distinct().Count())
{
GetConceptualAssociationNames(lstAssociationTypes, lstNames);
}
}
public override void Save(Type contextType, DbModel model)
{
if (contextType.GenericTypeArguments != null && contextType.GenericTypeArguments.Length > 0)
{
string name = contextType.GenericTypeArguments[0].Name;
List<string> storeModelNames = new List<string>();
storeModelNames.Add(name);
storeModelNames.Add("Entities");
#region StoreModel
List<string> storeModelAssociates = new List<string>();
if (model.StoreModel.AssociationTypes != null && model.StoreModel.AssociationTypes.Count() > 0)
{
GetConceptualAssociationNames(model.StoreModel.AssociationTypes.ToList(), storeModelNames);
var removedStoreAssociates = model.StoreModel.AssociationTypes.Where(a => !storeModelNames.Contains(a.Name)).ToList();
foreach (var removedAssociate in removedStoreAssociates)
{
var tmp = model.StoreModel.AssociationTypes.Where(a => a.Name == removedAssociate.Name).FirstOrDefault();
if (tmp != null)
{
model.StoreModel.RemoveItem(tmp);
}
}
}
storeModelNames = storeModelNames.Distinct().ToList();
var removedStoreModels = model.StoreModel.EntityTypes.Where(a => !storeModelNames.Contains(a.Name)).ToList();
foreach (var removedStoreModel in removedStoreModels)
{
var tmp = model.StoreModel.EntityTypes.Where(a => a.Name == removedStoreModel.Name).FirstOrDefault();
if (tmp != null)
{
model.StoreModel.RemoveItem(tmp);
}
}
var removeEntitySetBase = model.StoreModel.Container.BaseEntitySets.Where(a => !storeModelNames.Contains(a.ElementType.Name)).ToList();
foreach (var removedStoreModel in removeEntitySetBase)
{
var tmp = model.StoreModel.Container.BaseEntitySets.Where(a => a.Name == removedStoreModel.Name).FirstOrDefault();
if (tmp != null)
{
model.StoreModel.Container.RemoveEntitySetBase(tmp);
}
}
#endregion
#region ConceptualModel
List<string> conceptualAssociates = new List<string>();
if (model.ConceptualModel.AssociationTypes != null && model.ConceptualModel.AssociationTypes.Count() > 0)
{
GetConceptualAssociationNames(model.ConceptualModel.AssociationTypes.ToList(), storeModelNames);
var removedStoreAssociates = model.ConceptualModel.AssociationTypes.Where(a => !storeModelNames.Contains(a.Name)).ToList();
foreach (var removedAssociate in removedStoreAssociates)
{
var tmp = model.ConceptualModel.AssociationTypes.Where(a => a.Name == removedAssociate.Name).FirstOrDefault();
if (tmp != null)
{
model.ConceptualModel.RemoveItem(tmp);
}
}
}
storeModelNames = storeModelNames.Distinct().ToList();
var conceptualStoreModels = model.ConceptualModel.EntityTypes.Where(a => !storeModelNames.Contains(a.Name)).ToList();
foreach (var removedStoreModel in conceptualStoreModels)
{
var tmp = model.ConceptualModel.EntityTypes.Where(a => a.Name == removedStoreModel.Name).FirstOrDefault();
if (tmp != null)
{
model.ConceptualModel.RemoveItem(tmp);
}
}
var removeConcepEntitySetBase = model.ConceptualModel.Container.BaseEntitySets.Where(a => !storeModelNames.Contains(a.ElementType.Name)).ToList();
foreach (var removedStoreModel in removeConcepEntitySetBase)
{
var tmp = model.ConceptualModel.Container.BaseEntitySets.Where(a => a.Name == removedStoreModel.Name).FirstOrDefault();
if (tmp != null)
{
model.ConceptualModel.Container.RemoveEntitySetBase(tmp);
}
}
#endregion
#region Mapping
if (model.ConceptualToStoreMapping != null && model.ConceptualToStoreMapping.EntitySetMappings != null && model.ConceptualToStoreMapping.EntitySetMappings.Count() > 0)
{
List<System.Data.Entity.Core.Mapping.EntitySetMapping> lstEntitySetMappings = new List<System.Data.Entity.Core.Mapping.EntitySetMapping>();
bool isMappingExists = false;
foreach (var mapping in model.ConceptualToStoreMapping.EntitySetMappings)
{
isMappingExists = false;
if (mapping.EntityTypeMappings != null && mapping.EntityTypeMappings.Count > 0)
{
foreach (var subMapping in mapping.EntityTypeMappings)
{
if (subMapping.EntityTypes != null && subMapping.EntityTypes.Count > 0)
{
foreach (var ef in subMapping.EntityTypes)
{
if (!storeModelNames.Contains(ef.Name))
{
lstEntitySetMappings.Add(mapping);
isMappingExists = true;
break;
}
}
}
if (isMappingExists)
break;
}
}
}
lstEntitySetMappings = lstEntitySetMappings.Distinct().ToList();
if (lstEntitySetMappings.Count > 0)
{
foreach (var tmpMapping in lstEntitySetMappings)
{
var tmp = model.ConceptualToStoreMapping.EntitySetMappings.Where(a => a == tmpMapping).FirstOrDefault();
if (tmp != null)
{
model.ConceptualToStoreMapping.RemoveSetMapping(tmp);
}
}
}
}
#endregion
}
using (var writer = XmlWriter.Create(GetFilePath2(contextType), new System.Xml.XmlWriterSettings { Indent = true }))
{
EdmxWriter.WriteEdmx(model, writer);
}
}
public string GetFilePath2(Type contextType)
{
var filename = (contextType.GenericTypeArguments.Length > 0 ? contextType.GenericTypeArguments[0].Name : contextType.FullName) + ".edmx";
string path = Path.Combine(EFFoldPath, filename);
return path;
}
public override DbCompiledModel TryLoad(Type contextType)
{
string path = GetFilePath2(contextType);
if (File.Exists(path))
{
DateTime lastWriteTime = File.GetLastWriteTimeUtc(path);
DateTime lastWriteTimeDomainAssembly = File.GetLastWriteTimeUtc(contextType.Assembly.Location);
if (lastWriteTimeDomainAssembly > lastWriteTime)
{
File.Delete(path);
}
}
return LoadXml2(contextType, reader => {
var defaultSchema = GetDefaultSchema(contextType);
return EdmxReader.Read(reader, defaultSchema);
});
}
internal T LoadXml2<T>(Type contextType, Func<XmlReader, T> xmlReaderDelegate)
{
var filePath = GetFilePath2(contextType);
if (!File.Exists(filePath))
{
return default(T);
}
if (!FileIsValid2(contextType, filePath))
{
File.Delete(filePath);
return default(T);
}
using (var reader = XmlReader.Create(filePath))
{
return xmlReaderDelegate(reader);
}
}
public bool FileIsValid2(Type contextType, string filePath)
{
var contextCreated =
File.GetLastWriteTimeUtc(contextType.Assembly.Location);
var storeCreated = File.GetLastWriteTimeUtc(filePath);
return storeCreated >= contextCreated;
}
}
}
}
原文链接:C# EF的DbConfiguration加载优化,转载请注明来源!