https://msdn.microsoft.com/en-us/data/dn469601.aspx
Я пытаюсь реализовать стратегию, упомянутую в связанной статье, в моей огромной базе кода с более чем 500 объектами для повышения производительности. Я застрял со следующей проблемой.
Произошло исключение System.Data.Entity.Core.EntityCommandCompilationException
HResult = 0x8013193B Сообщение = Произошла ошибка при подготовке
определение команды. Подробности смотрите во внутреннем исключении.
Source = StackTrace:
Внутреннее исключение 1: MappingException: текущая модель больше не
соответствует модели, использованной для предварительной генерации отображений, как указано
посредством
ViewsForBaseEntitySets3193163ce55837363333438629c877839ae9e7b7494500b6fd275844cda6d343.MappingHashValue
имущество. Предварительно сгенерированные представления карт должны быть либо восстановлены с использованием
текущая модель или удалена, если отображаемые представления генерируются во время выполнения
следует использовать вместо Увидеть
http://go.microsoft.com/fwlink/?LinkId=318050 для получения дополнительной информации о
Представления отображения Entity Framework.
Вот что я пробовал. В оригинальной статье есть несколько пробелов относительно того, как это должно быть реализовано там, где я мог бы стать жертвой.
Шаг 1: Я создал класс, который расширяет DBMappingViewCache.
public class EFDbMappingViewCache : DbMappingViewCache
{
protected static string _mappingHashValue = String.Empty;
public override string MappingHashValue
{
get
{
return GetCachedHashValue();
}
}
public override DbMappingView GetView(EntitySetBase extent)
{
Dictionary<string, string> dict = GetMappedViewFromCache();
if (extent == null)
{
throw new ArgumentNullException("extent");
}
if(dict.ContainsKey(extent.Name))
{
return new DbMappingView(dict[extent.Name]);
}
return null;
}
public static string GetCachedHashValue()
{
string cachedHash;
string path = HttpContext.Current.Server.MapPath(@"~\EFCache\MappingHashValue.txt");
if (!File.Exists(path))
{
File.Create(path).Dispose();
}
using (var streamReader = new StreamReader(path, Encoding.UTF8))
{
cachedHash = streamReader.ReadToEnd();
}
return cachedHash;
}
public static void UpdateHashInCache(string hashValue)
{
string path = HttpContext.Current.Server.MapPath(@"~\EFCache\MappingHashValue.txt");
using (var streamWriter = new StreamWriter(path, false))
{
streamWriter.Write(hashValue);
}
}
private static void UpdateMappedViewInCache(Dictionary<EntitySetBase, DbMappingView> dict)
{
string path = HttpContext.Current.Server.MapPath(@"~\EFCache\MappingView.json");
Dictionary<String, String> stringDict = new Dictionary<string, string>();
foreach(var entry in dict)
{
stringDict[entry.Key.Name] = entry.Value.EntitySql.ToString();
}
var json = new JavaScriptSerializer().Serialize(stringDict);
using (var streamWriter = new StreamWriter(path, false))
{
streamWriter.Write(json);
}
}
private static Dictionary<String, string> GetMappedViewFromCache()
{
string path = HttpContext.Current.Server.MapPath(@"~\EFCache\MappingView.json");
var json = String.Empty;
using (var streamReader = new StreamReader(path, Encoding.UTF8))
{
json = streamReader.ReadToEnd();
}
Dictionary<String, string> mappedViewDict = new Dictionary<String, string>();
if (!String.IsNullOrEmpty(json))
{
var ser = new System.Web.Script.Serialization.JavaScriptSerializer();
mappedViewDict = ser.Deserialize<Dictionary<String, string>>(json);
}
return mappedViewDict;
}
public static void CheckAndUpdateEFViewCache()
{
using (var ctx = new CascadeTranscationsDbContext(DBHelper.GetConnString()))
{
var objectContext = ((IObjectContextAdapter)ctx).ObjectContext;
var mappingCollection = (StorageMappingItemCollection)objectContext.MetadataWorkspace
.GetItemCollection(DataSpace.CSSpace);
string computedHashValue = mappingCollection.ComputeMappingHashValue();
string currentHashValue = GetCachedHashValue();
SetHashValue(computedHashValue);
if (computedHashValue != currentHashValue)
{
UpdateHashInCache(computedHashValue);
IList<EdmSchemaError> errors = new List<EdmSchemaError>();
Dictionary<EntitySetBase, DbMappingView> result = mappingCollection.GenerateViews(errors);
UpdateMappedViewInCache(result);
}
}
}
}
Я сохранил хеш-значение и сопоставление, сгенерированные в файле, и извлек их в методе GetView ().
Я выставил открытый метод CheckAndUpdateEFViewCache (), который будет генерировать отображение представления при вызове и сохранять в файле.
Шаг 2: вызов метода CheckAndUpdateEFViewCache () из файла Global.asax метода Application_Start ().
Шаг 3: Включить сборку в файл, где контекст сначала вызывается.
[сборка: DbMappingViewCacheType (typeof (Models.Entities.MyDBContext), typeof (EFDbMappingViewCache))]
Я действительно не уверен, куда на самом деле должна идти эта сборочная линия. Информации об этом в ссылке нет. Есть действительно хороший шанс, что Step3 может быть там, где я ошибся.
Может кто-нибудь помочь с проблемой?