سلام
من از EF6.4.4 Code First در پروژه ی .Net Framework 4.6.2 استفاده میکنم (Visual Studio 17.5.3) .

برای افزایش سرعت و محاسبه نکردن MappingView برای اولین باری که از دستورات EF در هر بار که برنامه اجرا میشه ، دیدم که از Catch کردن MappingView (مثلا در یک فایل) و بعد خوندن MappingView از اون منبع استفاده میکنند (حداقل یکی از راه های حل مشکل کندی برای اولین بار که دستورات EF در هر بار اجرای برنامه استفاده میشه ، اینه) .

در لینک زیر ، نحوه ی انجام این کار اومده :


https://learn.microsoft.com/en-us/ef...---ef6-onwards

در بخش "Generating Views" ، به درستی اطلاعات MappingView را درون فایل xml ذخیره کردم .

=========================


اما برای قضیه ی لود مشکل دارم (نه اینکه مشکل لود از فایل داشته باشم) . بلکه در همون مقاله گفت که برای لودش ، یک کلاسی بسازید که از کلاس DbMappingViewCache ارث بری کنه (این کلاس هم دو تا عضو abstract در کلاس پدر را که عضوهای MappingHashValue و GetView هستند را باید پیاده سازی کنه) .

بعد هم در انتهای اون مقاله گفت که برای اینکه EF از این کلاس استفاده کنه ، باید از attribute زیر استفاده کنیم :


[assembly: DbMappingViewCacheType(typeof(PhoneBookDbContext), typeof(PhoneBookDbMappingViewCache))]


PhoneBookDbContext ، نام کلاس مشتق DbContext و PhoneBookDbMappingViewCache هم نام کلاس مشتق DbMappingViewCache ام هست .
چون اولش assembly داره ، تا جایی که میدونم ، این نوع attribute ها ، برای یک کلاس یا عضو خاصی نیستند و برای اون assembly بکار برده میشوند (اسمبلی من ، پروژه و لایه ی DataAccess.dll هست) و توصیه میشه که این نوع attribute ها را درون فایل assemblyinfo.cs قرار بدیم (که این فایل درون پوشه ی Properties در اون اسمبلی قرار داره) .
یعنی استفاده از این کلاس ، توسط ما صورت نمیگیره و توسط EF بصورت اتوماتیک صورت میگیره .

کدهای کلاس PhoneBookDbMappingViewCache ام هم اینه :


using DataAccess.ExceptionModule;
using DataAccess.SerializationModule;
using System;
using System.Collections.Generic;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure.MappingViews;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace DataAccess.EntityModule.Class.PreGeneratedView
{
internal class PhoneBookDbMappingViewCache : DbMappingViewCache
{
private DbMappingViewInfo dbMappingViewInfo;




public PhoneBookDbMappingViewCache()
{
this.dbMappingViewInfo = this.GetDbMappingViewInfo();
}




private DbMappingViewInfo GetDbMappingViewInfo()
{
string xmlFullFileName = "PreGeneratedMappingViews.xml";
string fullFilePath = AppDomain.CurrentDomain.BaseDirectory + xmlFullFileName;
if (File.Exists(fullFilePath) == false)
return null;


DbMappingViewInfo dbMappingViewInfo = XmlDataSerializer.ReadDataFromXmlFile<DbMappingVie wInfo>(xmlFullFileName);
return dbMappingViewInfo;
}




public override string MappingHashValue
{
get
{
return this.dbMappingViewInfo?.DbMappingHashValue;
}
}


public override DbMappingView GetView(EntitySetBase extent)
{
Debug.WriteLine("test\ntest\ntest");


if (extent == null)
throw new ArgumentNullException(nameof(extent), ExceptionMessage.argumentNullExceptionMessage);


EntityMappingViewInfoWrapper matchedEntityMappingViewInfoWrapper = this.dbMappingViewInfo?.EntityMappingViews?.Find(
(EntityMappingViewInfoWrapper currentEntityMappingView) =>
{
return currentEntityMappingView.EntityName == extent.Name;
});


if (matchedEntityMappingViewInfoWrapper == null || matchedEntityMappingViewInfoWrapper.EntitySql == null)
return null;


DbMappingView dbMappingView = new DbMappingView(matchedEntityMappingViewInfoWrapper. EntitySql);
return dbMappingView;
}




}
}


کد کلاس assemblyinfo.cs ام که فقط در خط اولش ، اون attribute را بهش اضافه کردم ، اینه :


using DataAccess.EntityModule.Class;
using DataAccess.EntityModule.Class.PreGeneratedView;
using System.Data.Entity.Infrastructure.MappingViews;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;


[assembly: DbMappingViewCacheType(typeof(PhoneBookDbContext), typeof(PhoneBookDbMappingViewCache))]


[assembly: AssemblyTitle("DataAccess")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DataAccess")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]


[assembly: ComVisible(false)]


[assembly: Guid("53e7049a-2c36-46da-b435-1ef77baa5306")]


[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]


من هم این کار را کردم و در متد GetView در کلاس PhoneBookDbMappingViewCache ، هم breakpoint و هم دستور Debug.WriteLine نوشتم اما هیچ کدوم شون اجرا نشدن .

میدونید علت چیه و چه کار باید کرد که اعضای این کلاس توسط EF فراخوانی و استفاده بشن؟


==============

من مشکل شبیه این را در دو پست زیر دیدم (هر دو ، یک سئوال هستند) اما جواب خاصی ندیدم که بهش داده باشند :

Can't get DbMappingViewCache to cache my views · Issue #1695 · dotnet/ef6 (github.com)
و
C#‎‎‎‎ - How to check if DbMappingViewCache caches the precompiled views - Stack Overflow

تشکر دوستان .