Base solution for your next web application

Activities of "TimMackey"

The resolution of #7635 obviated a need for this approach.

Converting to virtual solved the issue. See #7550 for complete solution.

The above suggested solution was only partially related to my problem. I solved the issue by conditionally compiling out foreign keys (but not the id) in tables that referenced referenced Tenant. i.e.

    [Table("Buildings")]
    public class Building : FullAuditedEntity , IMayHaveTenant
    {
#if !CUSTOM_DB_CONTEXT_LIB
        [ForeignKey("TenantId")]
        public virtual Tenant Tenant { get; set; }
#endif
        public virtual int? TenantId { get; set; }
        
        [Required]
        [StringLength(BuildingConsts.MaxBuildingNameLength, MinimumLength = BuildingConsts.MinBuildingNameLength)]
        public virtual string BuildingName { get; set; }
       ...
    }

This allows me to use the same table definition files in ANZ-generated context public class AnzAppDbContext : AbpZeroDbContext<Tenant, Role, User, AnzAppDbContext>, IAbpPersistedGrantDbContext and my custom context for .NET Core 2.2, which is...

using Microsoft.EntityFrameworkCore;

namespace CustomDbContextLibrary
{
    public class CustomDbContext : DbContext
    {
        public virtual DbSet<Building> Buildings { get; set; }
        ...
        public virtual DbSet<Room> Rooms { get; set; }

        public ExamDbContext(DbContextOptions<ExamDbContext> options)
           : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }
    }
}

The class constructor is

using Microsoft.EntityFrameworkCore;
#if CUSTOM_DB_CONTEXT_LIB
using CustomDbContextLibrary;
using DbContext = CustomDbContextLibrary.CustomDbContext;
#else
using  AnzApp.AnzAppDataModel;
using DbContext = AnzApp.EntityFrameworkCore.AnzAppDbContext;
#endif
using Abp.EntityFrameworkCore;
using Abp.Domain.Uow;
using System.Transactions;
using Microsoft.Extensions.Configuration;
using Microsoft.AspNetCore.Hosting;

private readonly IDbContextProvider<DbContext> _dbContextProvider;
private readonly IConfigurationRoot _appConfiguration;
private readonly DbContextOptionsBuilder<DbContext> _dbContextOptionsBuilder;
//-----------------------------------------------------------------------------------------
public CreateSomethingClass(
    IDbContextProvider<DbContext> dbContextProvider,
    IHostingEnvironment hostingEnvironment
    )
{
    _dbContextProvider = dbContextProvider;
    _appConfiguration = hostingEnvironment.GetAppConfiguration();
    _dbContextOptionsBuilder = new DbContextOptionsBuilder<DbContext>();
    string connStr = _appConfiguration.GetConnectionString("Default");
    _dbContextOptionsBuilder.UseSqlServer(connStr);
}

Usage is

 public virtual bool Create(string guid, string rootFolder)
 {
        using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
        {
            DbContext context = new DbContext(_dbContextOptionsBuilder.Options);
            {
                Building bldg = context.Buildings.First(x => x.BuildingName == "Electric Tower") ;
                bldg.BuildingName = "Tower Two";
                context.SaveChanges();
                ...
                // thousands of lines of code not shown
             }
          }
 }

This provides performance equivalent to ASP.NET EntityFramework when referencing many tables for high frequency bursts of create/read/update rows.

Making the Create method virtual, as suggested in ticket #7635 eliminates transactional nature of db access. This resolves all issues.

@maliming and @ismcagdas - Thank you for your all your suggestions.

When will version 7.2.3 be available for Download?

WorkingDirectory confirmed.

@ismcagdas,

I'm not confident that converting my app from EF to SQL would be effective. it's a lot of code that would need to be changed, and I'm concerned that SQL updates will not effect until transaction/thread completion after all the changes.

I'm using EF in ASP.NET Framework 4.5.2 in my original app; excellent performance and the db is updated upon context.SaveChanges(). EF in Zero/Core however has slower performance and the db is NOT updated upon context.SaveChanges(); the db is updated upon transaction/thread completion.

I think the mystery now is why non-transactional unit of work attributes (as recommended by @maliming) are not working.

I implemented the suggested code changes. Records are not committed to the physical db and performance is 3X SLOWER than the same code in ASP.NET.

Is there anything I might have missed that would be preventing commit or result in degraded performance?

using System;
using System.Collections.Generic;
using System.Linq;

#if NETFRAMEWORK
using DataModelLibrary.Exams;
using DbContext = DataModelLibrary.Exams.DbContext_Exam;
#endif

#if NETCOREAPP   // https://docs.microsoft.com/en-us/dotnet/standard/frameworks
using Abp.Domain.Uow;
using Abp.EntityFrameworkCore;
using System.Transactions;

using ngTTM.TtmDataModel;
using DbContext = ngTTM.EntityFrameworkCore.ngTTMDbContext;
#endif

// for clarity, all NETFRAMEWORK-specific code has been removed
namespace JobsLibrary
{
    public class CreateExamsDemo
    {
        //-----------------------------------------------------------------------------------------
        private readonly IDbContextProvider<DbContext> _dbContextProvider;
        //-----------------------------------------------------------------------------------------
        public CreateExamsDemo(IDbContextProvider<DbContext> dbContextProvider)
        {
            _dbContextProvider = dbContextProvider;
        }
        //-----------------------------------------------------------------------------------------
        [UnitOfWork(IsDisabled = true)]
        // [UnitOfWork(isTransactional: false)]
        public bool Create(string guid, string rootFolder)
        {
            DateTime _StartTime = DateTime.Now;
            try
            {
                using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
                {
                    DbContext context = _dbContextProvider.GetDbContext();
                    {
                        Exam exam = context.Exams.First(x => x.Guid == guid);

                        // not shown are calls to other functions accessing many db tables
                        // the code fragment below illustrates the concept

                        List<ExamQuestion> examQuestionsList = new List<ExamQuestion>();
                        // add multiple ExamQuestion to list
                        context.ExamQuestions.AddRange(examQuestionsList);
                        // acquire table "id" values used in next processing steps (not shown)
                        context.SaveChanges();

                        // typical execution time in NETFRAMEWORK is approx. 4 minutes
                        // typical execution time in NETCOREAPP is approx. 16 minutes
                        exam.CreateDuration = (float)(DateTime.Now - _StartTime).TotalSeconds;
                        context.SaveChanges();
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                // Exception handler
                return false;
            }
            //-----------------------------------------------------------------------------------------
        }
    }
}

Where does this function reside? How and when is it invoked? The Abp documentation page does not answer these questions.

Why is it not a good practice? How is a legacy Console app that was created outside the Abp/Zero universe executed?

Created a project based on Zero's Demo project.

Unable to reproduce the error

Exception: Unable to determine the relationship represented by navigation property 'User.DeleterUser' of type 'User'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

in the Demo project due, I suspect, to the specific table/foreign key relationships in my db, which I would be impractical to reproduce in a demo project.

I will submit a new issue that I need to resolve that may reveal a solution to this issue.

Showing 161 to 170 of 285 entries