[英]Generating Mapping views from code - EF6
https://msdn.microsoft.com/en-us/data/dn469601.aspx https://msdn.microsoft.com/en-us/data/dn469601.aspx
I am trying to get the strategy mentioned in the linked article implemented in my huge codebase with over 500 entities to improve performance. 我试图在我的庞大代码库中实现链接文章中提到的策略,该策略包含500多个实体,以提高性能。 I am stuck with the following issue. 我坚持以下问题。
System.Data.Entity.Core.EntityCommandCompilationException occurred 发生System.Data.Entity.Core.EntityCommandCompilationException
HResult=0x8013193B Message=An error occurred while preparing the command definition. HResult = 0x8013193B消息=准备命令定义时发生错误。 See the inner exception for details. 有关详细信息,请参见内部异常。
Source= StackTrace: 来源= StackTrace:Inner Exception 1: MappingException: The current model no longer matches the model used to pre-generate the mapping views, as indicated by the ViewsForBaseEntitySets3193163ce55837363333438629c877839ae9e7b7494500b6fd275844cda6d343.MappingHashValue property. 内部异常1:MappingException:当前模型不再与用于预生成映射视图的模型匹配,如ViewsForBaseEntitySets3193163ce55837363333438629c877839ae9e7b7494500b6fd275844cda6d343.MappingHashValue属性所指示。 Pre-generated mapping views must be either regenerated using the current model or removed if mapping views generated at runtime should be used instead. 如果要改用运行时生成的映射视图,则必须使用当前模型重新生成或删除预先生成的映射视图。 See http://go.microsoft.com/fwlink/?LinkId=318050 for more information on Entity Framework mapping views. 有关实体框架映射视图的更多信息,请参见http://go.microsoft.com/fwlink/?LinkId=318050 。
Here's what I have tried. 这是我尝试过的。 There are a few gaps in the original article on how it needs to be implemented where I might have fallen prey. 原始文章中有一些空白,说明在我可能沦为猎物的地方如何实施它。
Step 1: I have created a class that extends DBMappingViewCache. 步骤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);
}
}
}
}
I have stored the hashvalue and mapping generated in a file and retrieved it in GetView() method. 我已将生成的哈希值和映射存储在文件中,并在GetView()方法中对其进行了检索。
I have exposed a public CheckAndUpdateEFViewCache() method which will generate the view mapping when called and store in file. 我公开了一个公共CheckAndUpdateEFViewCache()方法,该方法将在调用时生成视图映射并存储在文件中。
Step2: Call the CheckAndUpdateEFViewCache() from Global.asax file Application_Start() method. 步骤2:从Global.asax文件Application_Start()方法调用CheckAndUpdateEFViewCache()。
Step3: Include assembly in the file where context is first called. 步骤3:在第一次调用上下文的文件中包含程序集。 [assembly: DbMappingViewCacheType(typeof(Models.Entities.MyDBContext), typeof(EFDbMappingViewCache))] [程序集:DbMappingViewCacheType(typeof(Models.Entities.MyDBContext),typeof(EFDbMappingViewCache))]
I am really not sure where this assembly line actually needs to go. 我真的不确定这条装配线实际需要去哪里。 There is no information on it in the link. 链接中没有任何信息。 There is a really good chance that Step3 might be where i have gone wrong. Step3很有可能是我出错的地方。
Can someone help with the problem ? 有人可以解决这个问题吗?
The issue I had faced was because I already had a mapped file generated using EF Tools and it was registered. 我遇到的问题是因为我已经有使用EF工具生成的映射文件,并且该文件已注册。 When the configuration I wrote attempted to register one more time, EF threw an error. 当我编写的配置尝试再次注册时,EF抛出错误。
Further I want to add that Cached DB model store improved the performance several folds and I ended up using just that in my project. 此外,我想补充一点,即缓存数据库模型存储将性能提高了几倍,而我最终仅在项目中使用了它。 Link to Cached DB model store usage 链接到缓存的数据库模型存储使用情况
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.