I am using (core+angular) v4.5.1, and need to add a service for creating a record into database table. The service works fine until I insert the current username into the record.
I am using two database with separated DbContext. I need to get the username by GetCurrentUser().UserName from DbContext1 and insert the username into an entity in DbContext2. It seems not allowed this operation, and throw out an exception:
Mvc.ExceptionHandling.AbpExceptionFilter - The specified transaction is not associated with the current connection. Only transactions associated with the current connection may be used.
I searched it on forum and found a similar issue on "2 Context - Transaction Error #372". It seems saying the issue solved on "the milestones: v4.4, v4.5 on Aug 25 ". I wonder if my above issue is new? If so, can you give a clue for a workaround?
Thanks,
12 Answer(s)
-
0
Switch to DbContext transaction API in PreInitialize method of YourEntityFrameworkModule:
Configuration.ReplaceService<IEfCoreTransactionStrategy, DbContextEfCoreTransactionStrategy>(DependencyLifeStyle.Transient);
-
0
Thank you for your prompt response!
I am trying to add that line into PreInitialize method of EntityFrameworkCoreModule, with 2 namespaces: using Abp.EntityFrameWorkCore.Uow; using Abp.Dependency;
but got a compile error: The non-generic method 'IAbpStartupConfiguration.ReplaceService(Type, Action)' cannot be used with type arguments.
What did I miss?
-
0
Add this namespace:
using Abp.Configuration.Startup;
-
0
Just added this namespace, and passed compile, but unfortunately, it still throws the same exception.
Any idea?
-
0
Have you added both DbContexts like in this comment: https://github.com/aspnetzero/aspnet-zero-core/issues/372#issuecomment-327497309
-
0
Yes. My both DbContexts work fine, if use them separately. For example, I can get "accessToken" from /api/TokenAuth/Authenticate. The user entity is in ProjectDbContext. I can get "myEntity" from CustomDbContext.
There seems no built-in way to add multiple DbContexts for multiple databases so far. I tried the way your indicated, but it does not work for me. My CustomDbContext never connected in that way. I know I must miss something. I am still waiting for an "official" release for using multiple DbContext.
Currently, I use my own workaround. I made an "AppEntityFrameworkCoreModule" which is very similar to "ProjectEntityFrameworkCoreModule", but with different connection string. I added "typeof(App1EntityFrameworkCoreModule)" on the top of WebCoreModule, so both DbContexts can be initialized. They work fine until the issue I met today.
Here is my problem code for inserting a record into the table in the 2nd database. The "Obj" is an entity in the 2nd DbContext.
public async Task CreateObj(ObjListDto input) { var obj = ObjectMapper.Map<Obj>(input); obj.Username = GetCurrentUser().UserName; //this line caused the exception await _objRepository.InsertAsync(obj); }
Any idea?
-
0
Pass in the proper connection string to UseSqlServer.
You know it's solved, but you refuse to use the solution?
-
0
Pass in the proper connection string to UseSqlServer.
I even tried to hard-coded the connection strings, but still got SAME exception.
You know it's solved, but you refuse to use the solution?
I tried this "solution", but still got SAME exception.
Let me change an angle to state my question. I want to get the current username while inserting a record into the 2nd database. My following code throws exception:
public async Task CreateObj(ObjListDto input) { var obj = ObjectMapper.Map<Obj>(input); obj.Username = GetCurrentUser().UserName; //this line caused the exception await _objRepository.InsertAsync(obj); }
Can you give me another way to get the current username ?
Thanks,
-
0
Try this:
public async Task CreateObj(ObjListDto input) { string username; using (var uow = _unitOfWorkManager.Begin(TransactionScopeOption.Suppress) { username = GetCurrentUser().UserName; uow.Complete(); } var obj = ObjectMapper.Map<Obj>(input); obj.Username = username; await _objRepository.InsertAsync(obj); }
-
0
Great!!! It works and solved my issue. :o
Thank you very much!
-
0
The above aaron's code works fine in my methods. Now I have multiple methods (createObj, updateObj, GetObj, and so on) which need the same username, so I moved the same code into the service class constructor. The "GetCurrentUser().UserName;" always throw out exception: Invalid object name 'AbpUsers'.
What do I miss?
Thanks,
-
0
Don't do it in the constructor. You can make it a method.