-
-
Save hikalkan/e035271493fa9fbd7fa026d44c690aa9 to your computer and use it in GitHub Desktop.
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Abp.Collections.Extensions; | |
using Abp.Dependency; | |
using Abp.Domain.Uow; | |
using Abp.EntityFramework.Repositories; | |
using Abp.MultiTenancy; | |
namespace Abp.EntityFramework | |
{ | |
public class MyDbContextTypeMatcher : IDbContextTypeMatcher | |
{ | |
private readonly ICurrentUnitOfWorkProvider _currentUnitOfWorkProvider; | |
private readonly Dictionary<Type, List<Type>> _dbContextTypes; | |
public MyDbContextTypeMatcher(ICurrentUnitOfWorkProvider currentUnitOfWorkProvider) | |
{ | |
_currentUnitOfWorkProvider = currentUnitOfWorkProvider; | |
_dbContextTypes = new Dictionary<Type, List<Type>>(); | |
} | |
public virtual void Add(Type sourceDbContextType, Type targetDbContextType) | |
{ | |
if (!_dbContextTypes.ContainsKey(sourceDbContextType)) | |
{ | |
_dbContextTypes[sourceDbContextType] = new List<Type>(); | |
} | |
_dbContextTypes[sourceDbContextType].Add(targetDbContextType); | |
} | |
public virtual Type GetConcreteType(Type sourceDbContextType) | |
{ | |
//TODO: This can also get MultiTenancySide to filter dbcontexes | |
//TODO: Can be optimized by extracting/caching MultiTenancySideAttribute attributes for DbContexes. | |
//Get possible concrete types for given DbContext type | |
var allTargetTypes = _dbContextTypes.GetOrDefault(sourceDbContextType); | |
if (allTargetTypes.IsNullOrEmpty()) | |
{ | |
//Not found any target type, return the given type if it's not abstract | |
if (sourceDbContextType.IsAbstract) | |
{ | |
throw new AbpException("Could not find a concrete implementation of given DbContext type: " + sourceDbContextType.AssemblyQualifiedName); | |
} | |
return sourceDbContextType; | |
} | |
if (allTargetTypes.Count == 1) | |
{ | |
//Only one type does exists, return it | |
return allTargetTypes[0]; | |
} | |
//Will decide the target type with current UOW, so it should be in a UOW. | |
if (_currentUnitOfWorkProvider.Current == null) | |
{ | |
throw new AbpException("GetConcreteType method should be called in a UOW."); | |
} | |
var currentTenancySide = _currentUnitOfWorkProvider.Current.GetTenantId() == null | |
? MultiTenancySides.Host | |
: MultiTenancySides.Tenant; | |
var multiTenancySideContexes = allTargetTypes.Where(type => | |
{ | |
var attrs = type.GetCustomAttributes(typeof(MultiTenancySideAttribute), true); | |
if (attrs.IsNullOrEmpty()) | |
{ | |
return false; | |
} | |
return ((MultiTenancySideAttribute)attrs[0]).Side.HasFlag(currentTenancySide); | |
}).ToList(); | |
//Try to get the DbContext which is for current multitenancy side. | |
if (multiTenancySideContexes.Count == 1) | |
{ | |
return multiTenancySideContexes[0]; | |
} | |
//Try to get the DbContext which not defined AutoRepositoryTypesAttribute | |
var defaultRepositoryContexes = allTargetTypes.Where(type => !type.IsDefined(typeof(AutoRepositoryTypesAttribute), true)).ToList(); | |
if (defaultRepositoryContexes.Count == 1) | |
{ | |
return defaultRepositoryContexes[0]; | |
} | |
//Generating exception | |
if (multiTenancySideContexes.Count > 1) | |
{ | |
throw new AbpException(string.Format( | |
"Found more than one concrete type for given DbContext Type ({0}) define MultiTenancySideAttribute with {1}. Found types: {2}.", | |
sourceDbContextType, | |
currentTenancySide, | |
multiTenancySideContexes.JoinAsString(", ") | |
)); | |
} | |
throw new AbpException(string.Format( | |
"Found more than one concrete type for given DbContext Type ({0}) but none of them defines MultiTenancySideAttribute with {1}. Found types: {2}.", | |
sourceDbContextType, | |
currentTenancySide, | |
multiTenancySideContexes.JoinAsString(", ") | |
)); | |
} | |
} | |
} |
Here it is.I have manually merged all the code changes according to the latest version.Did I miss something here ?
private async Task<IQueryable<LinkedUserDto>> CreateLinkedUsersQuery(string sorting)
{
var currentUserIdentifier = AbpSession.ToUserIdentifier();
var currentUserAccount = await _userLinkManager.GetUserAccountAsync(AbpSession.ToUserIdentifier());
return (from userAccount in _userAccountRepository.GetAll()
join tenant in _tenantRepository.GetAll() on userAccount.TenantId equals tenant.Id into tenantJoined
from tenant in tenantJoined.DefaultIfEmpty()
where
(userAccount.TenantId != currentUserIdentifier.TenantId ||
userAccount.UserId != currentUserIdentifier.UserId) &&
userAccount.UserLinkId.HasValue &&
userAccount.UserLinkId == currentUserAccount.UserLinkId
select new LinkedUserDto
{
Id = userAccount.UserId,
TenantId = userAccount.TenantId,
TenancyName = tenant == null ? "." : tenant.TenancyName,
Username = userAccount.UserName,
LastLoginTime = userAccount.LastLoginTime
}).OrderBy(sorting);
}
I will want help from my partner to check this. For now, can you change GetRecentlyUsedLinkedUsers method to just return an empty list to see if there are any other problems.
I have done this.But still the same error.
recentlyUsedlinkedUsers.Clear();
return new ListResultOutput<LinkedUserDto>(recentlyUsedlinkedUsers);
It's coming on this line : Before the Clear()
method.
var recentlyUsedlinkedUsers = await query.Skip(0).Take(3).ToListAsync();
Hi,
Shall I put this issue on the Main repo or is this place enough ?
Please continue on https://github.com/aspnetzero/aspnet-zero/issues/224
Hi! I also have the problem of "Found more than one concrete type for given dbcontext type" after I upgrade from 0.8.2.0 to 0.9.3.0. Actually, I use DD design and i have many bounded contexts based on modules i have. Those bounded contexts uses only one single database or one connection string. For 0.8.2.0 version, I can do it without any problems and no need to define a custom repository since different bounded contexts contain different entities mapping and ASP.NET Zero design is smart enough to use the right bounded context. Here, i would like to confirm, for version 0.9.3.0, do i need to define each custom repository for each bounded context i have or is there anyway I can still enjoy using one repository for all bounded contexts?
Maybe your that code is a bit old. Can you share UserLinkAppService's CreateLinkedUsersQuery method?