Abp.EntityFrameworkCore interface does not implement IDbSet interface as specified on this page: https://aspnetboilerplate.com/Pages/Documents/EntityFramework-Integration?searchKey=AbpDbContext
I want to access MS EFCore directly instead of using Repository (which runs 15X slower than ASP.NET EF). My project is Angluar/Core.
When 'Abp.EntityFrameworkCore' is included in my project I keep getting the following error at Web.Host.Startup.cs, line 134: System.TypeLoadException HResult=0x80131522 Message=Method 'get_IsTraceEnabled' in type 'Abp.Castle.Logging.Log4Net.Log4NetLogger' from assembly 'Abp.Castle.Log4Net, Version=4.6.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation. Source=Abp.Castle.Log4Net
19 Answer(s)
-
0
use Abp.EntityFrameworkCore package
https://aspnetboilerplate.com/Pages/Documents/Entity-Framework-Core
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Implemented code per the above link.
Error occurs in Startup.cs at "//Configure Log4Net logging" on "AddFacility" method.
System.TypeLoadException HResult=0x80131522 Message=Method 'get_IsTraceEnabled' in type 'Abp.Castle.Logging.Log4Net.Log4NetLogger' from assembly 'Abp.Castle.Log4Net, Version=4.6.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation. Source=Abp.Castle.Log4Net StackTrace: at Abp.Castle.Logging.Log4Net.Log4NetLoggerFactory.Create(String name) at Castle.Facilities.Logging.LoggingFacility.RegisterDefaultILogger(ILoggerFactory factory) at Castle.Facilities.Logging.LoggingFacility.Init() at Castle.MicroKernel.DefaultKernel.AddFacility(IFacility facility) at Castle.Windsor.WindsorContainer.AddFacility[T](Action`1 onCreate) at ngTTM.Web.Startup.Startup.<ConfigureServices>b__4_6(AbpBootstrapperOptions options) in C:\Users\Tim\Documents\__ngTTMv700\aspnet-core\src\ngTTM.Web.Host\Startup\Startup.cs:line 146 at Abp.AbpBootstrapper..ctor(Type startupModule, Action`1 optionsAction) at Abp.AbpBootstrapper.Create[TStartupModule](Action`1 optionsAction) at Abp.AspNetCore.AbpServiceCollectionExtensions.AddAbpBootstrapper[TStartupModule](IServiceCollection services, Action`1 optionsAction) at Abp.AspNetCore.AbpServiceCollectionExtensions.AddAbp[TStartupModule](IServiceCollection services, Action`1 optionsAction) at ngTTM.Web.Startup.Startup.ConfigureServices(IServiceCollection services) in C:\Users\Tim\Documents\__ngTTMv700\aspnet-core\src\ngTTM.Web.Host\Startup\Startup.cs:line 143Web.Host/Startup/Startup.c
public IServiceProvider ConfigureServices(IServiceCollection services) { //MVC services.AddMvc(options => { options.Filters.Add(new CorsAuthorizationFilterFactory(DefaultCorsPolicyName)); }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSignalR(options => { options.EnableDetailedErrors = true; }); //Configure CORS for angular2 UI services.AddCors(options => { options.AddPolicy(DefaultCorsPolicyName, builder => { //App:CorsOrigins in appsettings.json can contain more than one address with splitted by comma. builder .WithOrigins( // App:CorsOrigins in appsettings.json can contain more than one address separated by comma. _appConfiguration["App:CorsOrigins"] .Split(",", StringSplitOptions.RemoveEmptyEntries) .Select(o => o.RemovePostFix("/")) .ToArray() ) .SetIsOriginAllowedToAllowWildcardSubdomains() .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); IdentityRegistrar.Register(services); AuthConfigurer.Configure(services, _appConfiguration); //Identity server if (bool.Parse(_appConfiguration["IdentityServer:IsEnabled"])) { IdentityServerRegistrar.Register(services, _appConfiguration); } if (WebConsts.SwaggerUiEnabled) { //Swagger - Enable this line and the related lines in Configure method to enable swagger UI services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new Info { Title = "ngTTM API", Version = "v1" }); options.DocInclusionPredicate((docName, description) => true); options.UseReferencedDefinitionsForEnums(); options.ParameterFilter<SwaggerEnumParameterFilter>(); options.SchemaFilter<SwaggerEnumSchemaFilter>(); options.OperationFilter<SwaggerOperationIdFilter>(); options.OperationFilter<SwaggerOperationFilter>(); options.CustomDefaultSchemaIdSelector(); //Note: This is just for showing Authorize button on the UI. //Authorize button's behaviour is handled in wwwroot/swagger/ui/index.html options.AddSecurityDefinition("Bearer", new BasicAuthScheme()); }); } //Recaptcha services.AddRecaptcha(new RecaptchaOptions { SiteKey = _appConfiguration["Recaptcha:SiteKey"], SecretKey = _appConfiguration["Recaptcha:SecretKey"] }); if (WebConsts.HangfireDashboardEnabled) { //Hangfire(Enable to use Hangfire instead of default job manager) services.AddHangfire(config => { config.UseSqlServerStorage(_appConfiguration.GetConnectionString("Default")); }); } if (WebConsts.GraphQL.Enabled) { services.AddAndConfigureGraphQL(); } // configure NgTtmAbpDbContext context services.AddAbpDbContext<NgTtmAbpDbContext>(options => { options.DbContextOptions.UseSqlServer(options.ConnectionString); }); //Configure Abp and Dependency Injection return services.AddAbp<ngTTMWebHostModule>(options => { //Configure Log4Net logging options.IocManager.IocContainer.AddFacility<LoggingFacility>( f => f.UseAbpLog4Net().WithConfig("log4net.config") ); options.PlugInSources.AddFolder(Path.Combine(_hostingEnvironment.WebRootPath, "Plugins"), SearchOption.AllDirectories); }); }DbContextLibrary/NgTtmAbpDbContext.cs
using Abp.EntityFrameworkCore; using Abp.Modules; using Microsoft.EntityFrameworkCore; using ngTTM.TtmDataModel; namespace DbContextLibrary { [DependsOn(typeof(AbpEntityFrameworkCoreModule))] public class NgTtmAbpDbContext : AbpDbContext { public virtual DbSet<AnswerMatch> AnswerMatchs { get; set; } public virtual DbSet<Answer> Answers { get; set; } public virtual DbSet<Question> Questions { get; set; } public virtual DbSet<QuestionBank> QuestionBanks { get; set; } public NgTtmAbpDbContext(DbContextOptions<NgTtmAbpDbContext> options) : base(options) { } } }Web.Host/Startup/ngTTMWebHostModule.cs
public override void PreInitialize() { Configuration.Modules.AbpWebCommon().MultiTenancy.DomainFormat = _appConfiguration["App:ServerRootAddress"] ?? "http://localhost:22742/"; Configuration.Modules.AspNetZero().LicenseCode = _appConfiguration["AbpZeroLicenseCode"]; Configuration.DefaultNameOrConnectionString = GetConnectionString("Default"); } private string GetConnectionString(string conn) { var appsettingsjson = JObject.Parse(File.ReadAllText("appsettings.json")); var dbConnectionStrings = (JObject)appsettingsjson["ConnectionStrings"]; string connStr = dbConnectionStrings.Property("Default").Value.ToString(); return connStr; }Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Method 'get_IsTraceEnabled' in type 'Abp.Castle.Logging.Log4Net.Log4NetLogger' from assembly 'Abp.Castle.Log4Net, Version=4.6.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
https://github.com/aspnetboilerplate/aspnetboilerplate/issues/4445#issuecomment-495637354 https://github.com/aspnetboilerplate/aspnetboilerplate/pull/4539
Usually you only need to upgrade the ABP package.
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Upgraded Abp.Castle.Log4Net, Abp.RedisCcache, Abp, Abp.ZeroCore from 4.6.0 to 4.8.1. Startup works fine. Using context causes Exception:
Message: LoadQuestionsXml.cs, ParseQuestionFile Exception Type: System.InvalidOperationException Exception: No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext. Source: Microsoft.EntityFrameworkCore Stack Trace: at Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context) at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.get_Model() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider() at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) at ImportFilesLibrary.LoadQuestionsXml.ParseQuestionFile(MemoryStream FileContent, Int32 QuestionBankId, Nullable`1 userId) in C:\Users\Tim\Documents\__ngTTMv700\aspnet-core\...myfile.cs...at " var data = context.QuestionBanks.FirstOrDefault(b => b.Id == 123);"
public class myClass { private static DbContextOptions<NgTtmAbpDbContext> dbContextOptions = new DbContextOptions<NgTtmAbpDbContext>(); public void MyFunction() { using (NgTtmAbpDbContext context = new NgTtmAbpDbContext(dbContextOptions)) { var data = context.QuestionBanks.FirstOrDefault(b => b.Id == 123); }Tried resolving error message, but Google searched solutions did not work.
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
In general you should not use AbpDbContext directly. You should use Repository. https://aspnetboilerplate.com/Pages/Documents/Repositories
I suggest you first check the abp & abp zero documentation.
https://aspnetboilerplate.com/Pages/Documents/ https://docs.aspnetzero.com/documents/common/latest/
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
I initially migrated some ASP.NET code to my ANZ app and used injection and IRepository as is used throughout ANZ. However, the performance for db-intensive operations is 15X SLOWER (due I surmise to the transactional nature of the interface). The db-intensive portion of my app is not built on the transaction model. Your first reply in this thread directed me to Enitity-Framework-Core, which I implemented. Now you're telling me that I shouldn't use it. The app I'm migrating from ASP.NET accessed EF directly. ANZ InitialHostDbBuilder class uses EF context directly. I need to access EF directly for performance reasons. Why can't access context directly in my app? Given https://aspnetboilerplate.com/Pages/Documents/Entity-Framework-Core is published documentation, how to I make it work?
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
You can try to get DbContext using IDbContextProvider instead of creating it manually.
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Could you please direct me to the documentation and some sample code?
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Very simple, inject the
IDbContextProviderinterface and then call the method to get theDbContext.public interface IDbContextProvider<out TDbContext> where TDbContext : DbContext { TDbContext GetDbContext(); TDbContext GetDbContext(MultiTenancySides? multiTenancySide ); }https://github.com/aspnetzero/aspnet-zero-core/blob/16582df85fbceba18fe61fdd613d1093ef25921c/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Application/HealthChecks/AbpZeroTemplateDbContextUsersHealthCheck.cs#L14
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
I implemented the changes as described above. My app compiles and runs without encountering Exceptions. The records in the db are as expected. However, the performance of the IDbContextProvider interface is 10X SLOWER than the equivalent MS EntityFramework context db access in ASP.NET, and is transactional. No data is actually written to the db until the thread completes and the IDbContextProvider is Disposed by the task caller. Multiple calls to "context.SaveChanges()" have no effect on the db. Why must I use IDbContextProvider interface? How can I get better performance from this interface? How can I override the transactional nature of this interface (without resorting to more overhead via UnitOfWork)? Why can I not use MS EntityFrameworkCore directly? And if I can, how?
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Because the entire framework is based on dependency injection.
No database provider has been configured for this DbContext. ....
try
var builder = new DbContextOptionsBuilder<AbpZeroTemplateDbContext>(); builder.UseSqlServer(_appConfiguration.GetConnectionString("Default")); var db = new AbpZeroTemplateDbContext(builder.Options); var user = db.Users.FirstOrDefault();Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Getting an Exception when the above is implemented:
Exception Type: System.InvalidOperationException 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'. Source: Microsoft.EntityFrameworkCore Stack Trace: at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyMappingValidationConvention.Apply(InternalModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel() at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode) --- End of stack trace from previous location where exception was thrown --- at System.Lazy`1.CreateValue() at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() at lambda_method(Closure , ServiceProviderEngineScope ) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.get_Model() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable() at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider() at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) at ImportFilesLibrary.LoadQuestionsXml.ParseQuestionFile(MemoryStream FileContent, Int32 QuestionBankId, Nullable`1 userId) in C:\Users\Tim\Documents\__ngTTMv700\aspnet-core\ttm\ImportFilesLibrary\LoadQuestionsXml.cs:line 69at LoadQuestionsXml.cs:line 69 is fhe following code:
QuestionBank questionBank = context.QuestionBanks .FirstOrDefault(b => b.QuestionBankId == QuestionBankId);NgTtmAbpDbContext.cs
using Abp.EntityFrameworkCore; using Abp.Modules; using Microsoft.EntityFrameworkCore; using ngTTM.TtmDataModel; namespace DbContextLibrary { [DependsOn(typeof(AbpEntityFrameworkCoreModule))] public class NgTtmAbpDbContext : AbpDbContext { public virtual DbSet<AnswerMatch> AnswerMatchs { get; set; } public virtual DbSet<Answer> Answers { get; set; } public virtual DbSet<Question> Questions { get; set; } public virtual DbSet<QuestionBank> QuestionBanks { get; set; } public NgTtmAbpDbContext(DbContextOptions<NgTtmAbpDbContext> options) : base(options) { } } }Implemented the code fragment you suggested as:
var builder = new DbContextOptionsBuilder<NgTtmAbpDbContext>(); string connStr = _appConfiguration.GetConnectionString("Default"); builder.UseSqlServer(connStr); NgTtmAbpDbContext context = new NgTtmAbpDbContext(builder.Options);Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
hi @timmackey Can you reproduce your problem using Zero's Demo project? Send to: [email protected]
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
The previously reported Exception has been eliminated by modifying the class as follows:
public class NgTtmAbpDbContext : AbpZeroDbContext<Tenant, Role, User, NgTtmAbpDbContext>No Exceptions occur, however, an earlier created table is not being updated:
QuestionBank questionBank = context.QuestionBanks .FirstOrDefault(b => b.QuestionBankId == QuestionBankId); if (questionBank == null) { status.FailureReason = FailureReason("UnableToOpenQuestionBankId_0", QuestionBankId.ToString()); status.Success = false; return status; } questionBank.ItemsTotal = elementCount * 2; questionBank.ItemsProcessed = 0; context.SaveChanges();"context.SaveChanges();" is not updating QuestionBanks table.
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
hi @timmackey
The code you shared made me unable to determine the problem.
Can you reproduce your problem using Zero's Demo project? Send to: [email protected]
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
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.
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Hi @timmackey
Your last problem might be related to https://github.com/aspnetboilerplate/aspnetboilerplate/issues/4691
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
Hi @timmackey
Did you have a chance to try this ?
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image) -
0
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>, IAbpPersistedGrantDbContextand 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.
Markdown is supportedCopy & paste or drag & drop images (max 30 MB per image)
