عمل نکردن event ها

علی شاکری
3 فروردين ۱۴۰۲

سلام استاد

نمیدونم چرا event ها پابلیش نمیشن

میخام یک notification برای کاربر اضافه کنم و یک sms هم بدم  نمیشه 

دیباگم کردم ولی انگار event handler اجرا نمیشه

557

24 پاسخ
  • محمد اشرافی4 فروردين ۱۴۰۲

    سلام وقت بخیر ، Event رو پابلیش کردین ؟ توی این عکس ها که این اتفاق نیوفتاده ( قبلا توی متد SaveChangeAsync این کار رو انجام داده بودیم )

  • علی شاکری4 فروردين ۱۴۰۲

    بله استاد داخل همون متد save هست

    با همون custom publish که خودتون درست کردید

  • علی شاکری4 فروردين ۱۴۰۲

    الان گیر میده به save کردن نوتیفیکیشن یوزر

    میگه هنوز عملیات قبلی تموم نشده

  • محمد اشرافی5 فروردين ۱۴۰۲

    خطایی که میده رو بزارید ببینم چیه

  • علی شاکری5 فروردين ۱۴۰۲

    سلام استاد

    هیچ اروری نمیده

    طبق این عکس بعد از بریک پوینت اول به هیچ کدوم دیگه نمیرسه و پیام موفقیت میده

  • علی شاکری5 فروردين ۱۴۰۲

    استاد این ارور را با serilog گرفتم

    An exception occurred while iterating over the results of a query for context type '"EShop.Infrastructure.Persistent.Ef.ShopDbContext"'."
    
    ""System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
    
      at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
    
      at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()"
  • علی شاکری5 فروردين ۱۴۰۲
    System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
    
      at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
    
      at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
    
      at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
    
      at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable`1 asyncEnumerable, CancellationToken cancellationToken)
    
      at EShop.Infrastructure._Utilities.BaseRepository`1.GetTracking(Int64 id) in E:\Projects\EShop\EShop.Infrastructure\_Utilities\BaseRepository.cs:line 23
    
      at EShop.Application.Orders._EventHandlers.SendSmsOrderSendedEventHandler.Handle(OrderSended notification, CancellationToken cancellationToken) in E:\Projects\EShop\EShop.Application\Orders\_EventHandlers\SendSmsOrderSendedEventHandler.cs:line 27
  • محمد اشرافی9 فروردين ۱۴۰۲

    سلام مجدد ، مشکل از GetTracking اتونه ، به صورت معمولی دریافت اش کنید ببینم مشکل حل میشه 

    و مورد بعدی اینکه Notification هارو بهتره  توی  یه Aggregate  با User قرار ندین چون تعداد Notification ها میره بالا و برای هر بار گرفتن User باید کل Notification هارو هم از دیتابیس دریافت کنید

  • علی شاکری9 فروردين ۱۴۰۲

    سلام استاد

    مشکل حل نشد

    من اومدم کلا یه aggregate برای نوتیفیکیشن درست کردم و دوباره مثل عکس زیر تغییر دادم ولی مشکل داره

    فک کنم اصلا نمیشه در eventhandler با روش mediatR کلا کوئری بزنیم و اطلاعات واکشی کنیم و یا save کنیم

    چون عملیات save قبلی تموم نشده و ما اومدیم پابلیش رو در متد save قرار دادیم

  • علی شاکری9 فروردين ۱۴۰۲

    اینم خطاش

    {"@t":"2023-03-29T02:50:07.3537813Z","@mt":"An exception occurred while iterating over the results of a query for context type '{contextType}'.{newline}{error}","@l":"Error","@x":"System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()\r\n   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()","contextType":"EShop.Infrastructure.Persistent.Ef.ShopDbContext","newline":"\r\n","error":"System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()\r\n   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()","EventId":{"Id":10100,"Name":"Microsoft.EntityFrameworkCore.Query.QueryIterationFailed"},"SourceContext":"Microsoft.EntityFrameworkCore.Query","ActionId":"e7a0ee82-c8ba-4712-b756-f235b47c8043","ActionName":"/Admin/Orders/Show","RequestId":"0HMPG006EDKEE:00000115","RequestPath":"/Admin/Orders/Show/3","ConnectionId":"0HMPG006EDKEE"}
  • محمد اشرافی9 فروردين ۱۴۰۲

    طبیعتا نباید مشکی پیش بیاد چون هر چند بار بخوایم میتونیم SaveChange  رو فراخوانی کنیم ولی این وسط مشکلی که پیش میاد اینه که میوفته توی یه حلقه و هی Event رو پابلیش میکنه  ( چون توی EventHandler هم دوباره صداش می زنیم ، کاری که باید انجام بدین اینه که بعد از اینکه Event هارو پابلیش کردین ، لیست Event هارو پاک کنید ) 

    توی Aggregate root یه متد به اسم ClearEvents بسازید و صداش بزنید 

  • محمد اشرافی9 فروردين ۱۴۰۲

    یعنی به این شکل بشه :

     private async Task PublishEvents(List<AggregateRoot> modifiedEntities)
        {
            foreach (var entity in modifiedEntities)
            {
                var events = entity.DomainEvents.ToList();
                entity.ClearnEvents();
                foreach (var domainEvent in events)
                {
                    await _publisher.Publish(domainEvent,PublishStrategy.ParallelNoWait);
                }
            }
        }
  • علی شاکری9 فروردين ۱۴۰۲

    سلام استاد

    من اومدم این entity.DomainEvents.Clear(); رو بجای clearevents اضافه کردم ولی بازم کار نمیکنه

  • علی شاکری9 فروردين ۱۴۰۲
    private async Task PublishEvents(List<AggregateRoot> modifiedEntities)
        {
            foreach (var entity in modifiedEntities)
            {
                var events = entity.DomainEvents.ToList();
                entity.DomainEvents.Clear();
                foreach (var domainEvent in events)
                {
                    await _publisher.Publish(domainEvent, PublishStrategy.ParallelNoWait);
                }
            }
        }
  • علی شاکری9 فروردين ۱۴۰۲
    [22:25:47 ERR] An exception occurred while iterating over the results of a query for context type 'EShop.Infrastructure.Persistent.Ef.ShopDbContext'.
    System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
       at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
       at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
    System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
       at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
       at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
  • محمد اشرافی11 فروردين ۱۴۰۲

    SaveChange توی Event Handler رو بردارین مشکل حل میشه ؟

  • علی شاکری11 فروردين ۱۴۰۲

    سلام استاد

    بازم این ارور رو میده

    InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.
  • علی شاکری11 فروردين ۱۴۰۲

    استاد من اومدم در infrastructurebootstrapper کد رو به این تغییر دادم

    services.AddDbContext<ShopDbContext>(option =>
                {
                    option.UseSqlServer(connectionString);
                }, ServiceLifetime.Transient);

    سرویس لایف تایم رو به transient تغییر دادم و در eventhandler هم save را پاک نکردم و الان درست شد و کار میکنه

     

    به نظرتون این تغییر در servicelifetime مشکل ساز نمیشه؟

     

  • محمد اشرافی12 فروردين ۱۴۰۲

    فکر نمیکنم مشکل خاصی پیش ، به صورت پیشفرض خود اش Scope ه ، ولی اگر Singleton اش میکردین به مشکل میخورد

  • علی شاکری12 فروردين ۱۴۰۲

    خب استاد الان من باید تو همه پروژه های بزرگ این تغییر رو انجام بدم؟

    الان من از rich مدل استفاده کردم.به نظرم روش خوبیه فقط یکم توی کوئری گرفتن با dapper سختم بود.مثلا برای نوشتن کوئری صفحه بندی productshop هنوز کامل متوجه نشدم و از chatgpt کمک گرفتم خخخ

    الان برای نوشتن کوئری های پیچیده ابزار خاصی هست یا باید بشینیم و بنویسیم؟

  • محمد اشرافی12 فروردين ۱۴۰۲

    نه نیازی نیست من همیشه همینطور استفاده میکردم نمیدونم چرا براش شما این مشکل پیش اومده ولی ممکنه توی نسخه جدید اینطور شده باشه

    برای Query هم توی پروژه آخری بهتون گفتم میتونید از QueryContext استفاده کنید که خیلی Query گرفتن راحت میشه

  • علی شاکری13 فروردين ۱۴۰۲

    منتظرم پروژه digilearn کامل بشه بعد ببینم

    در کل میخاستم بدونم اگه کلا با دپر بخام بزنم چطوری میشه؟ابزار خاصی برای نوشتن کوئری های پیچیده نیست؟

  • محمد اشرافی13 فروردين ۱۴۰۲

    نه دیگه اگر بخواین Raw Sql استفاده کنید باید کد های SQL استفاده کنید

  • علی شاکری14 فروردين ۱۴۰۲

    ممنون استاد