نمایش نتایج 1 تا 3 از 3

نام تاپیک: مشکل عدم اجرای اعضای کلاس DbMappingViewCache در EF6.4

  1. #1

    مشکل عدم اجرای اعضای کلاس DbMappingViewCache در EF6.4

    سلام
    من از 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

    تشکر دوستان .

  2. #2

    نقل قول: مشکل عدم اجرای اعضای کلاس DbMappingViewCache در EF6.4

    تا اینجا متوجه شدم که اعضای کلاس PhoneBookDbMappingViewCache ، فقط یکبار و اونهم زمانی که فایل اش در حال ساخته شدن برای اولین بار هستند ، اجرا میشه .

    هر چند نوشتن فایل اش را در کلاس مشتقِ CreateDatabaseIfNotExists<PhoneBookDbContext> انجام دادم اما خوندن اش طبعا هیچ ربطی به این کلاس نباید داشته باشه و درون این کلاس ، اصلا از کلاسِ PhoneBookDbMappingViewCache استفاده نشد .
    نمیدونم علتش چیه!

  3. #3

    نقل قول: مشکل عدم اجرای اعضای کلاس DbMappingViewCache در EF6.4

    متوجه شدم که اعضای کلاس PhoneBookDbMappingViewCache ، موقع فراخوانی متد Database.Initialize ، فراخوانی نمیشن . بلکه موقعی که درخواست خواندن و یا نوشتن اطلاعات در جدول توسط موجودیت های EF داده میشه ، در این موقع فراخوانی میشن .

    هر چند فرق خاصی هم نداره . چون نمیدونم به چه علت ، قبل از فراخوانی اعضای کلاس PhoneBookDbMappingViewCache ، برای اولین باری که برنامه اجرا میشه ، (این درخواست خواندن یا نوشتن توسط EF) ، حدود 2 ثانیه طول میکشه که احتمالا بخاطر محاسبات Mapping View هست . تازه بعد از این 2 ثانیه ، شروع به اجرای اعضای کلاس PhoneBookDbMappingViewCache میکنه!!

    در صورتی که اصلا کلاس DbMappingViewCache را طراحی کردن که قبل از اینکه Mapping View را خودش بخواد محاسبه کنه ، اگه اطلاعاتش در جایی از قبل ، ذخیره شده بود ، از اون اطلاعات استفاده کنه . اما نمیدونم این باگ EF6.4.4 هست یا چیز دیگه که بعد از انجام کار ، تازه فراخونی اش میکنه !!

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •