Abp.ZeroCore.EntityFramework errors with indexes and lazy loading
See original GitHub issueThere are some bugs to be fixed with the Abp.ZeroCore.EntityFramework package in order to get it working with an ASP.NET Boilerplate ASP.NET Core project targeting the full .NET Framework and Entity Framework 6.
I have set a repository with the vanilla aspnetboilerplate template using asp.net core and EF6 here: aspnetboilerplate-core-entityframework6
Problems with indexes
EntityFramework 6 does not like adding indexes with key columns of type string with no length limit. In order to make migrations work I had to add the following code to my DbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// HACK: Added maximum length to avoid Index validation errors. EF6 does not allow nvarchar(MAX) for indexes
modelBuilder.Entity<RoleClaim>().Property(rc => rc.ClaimType).HasMaxLength(256);
modelBuilder.Entity<UserClaim>().Property(uc => uc.ClaimType).HasMaxLength(256);
modelBuilder.Entity<UserAccount>().Property(ua => ua.UserName).HasMaxLength(256);
modelBuilder.Entity<UserAccount>().Property(ua => ua.EmailAddress).HasMaxLength(256);
}
So I recommend you to add this length restrictions to those properties using constants like it’s already done for some other entities.
Problems with lazy loading
The provided respository project does build and EF migrations run correctly. But when I try to login through the web project or even running the unit tests, I am getting the following exception:
Message: System.InvalidOperationException : The property 'Tokens' on type 'User_259C3D76EAF67125930DAB5AF9DD530621C9839E2069AFE32437A1ECA12793DE' cannot be set because the collection is already set to an EntityCollection.
in System.Data.Entity.DynamicProxies.User_259C3D76EAF67125930DAB5AF9DD530621C9839E2069AFE32437A1ECA12793DE.set_Tokens(ICollection`1 )
in Abp.Authorization.Users.AbpUser`1..ctor()
in AbpCompanyName.AbpProjectName.Authorization.Users.User..ctor()
in lambda_method(Closure , Shaper )
in System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
in lambda_method(Closure , Shaper )
in System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
in System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
in System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
in System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
in System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
in System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
in System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
in System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
in System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
in AbpCompanyName.AbpProjectName.Tests.AbpProjectNameTestBase.<>c__DisplayClass18_0.<LoginAsTenant>b__1(AbpProjectNameDbContext context) in aspnetboilerplate-core-entityframework6\\aspnet-core\\test\\AbpCompanyName.AbpProjectName.Tests\\AbpProjectNameTestBase.cs:line 244
in AbpCompanyName.AbpProjectName.Tests.AbpProjectNameTestBase.UsingDbContext[T](Nullable`1 tenantId, Func`2 func) in aspnetboilerplate-core-entityframework6\\aspnet-core\\test\\AbpCompanyName.AbpProjectName.Tests\\AbpProjectNameTestBase.cs:line 177
in AbpCompanyName.AbpProjectName.Tests.AbpProjectNameTestBase.UsingDbContext[T](Func`2 func) in aspnetboilerplate-core-entityframework6\\aspnet-core\\test\\AbpCompanyName.AbpProjectName.Tests\\AbpProjectNameTestBase.cs:line 137
in AbpCompanyName.AbpProjectName.Tests.AbpProjectNameTestBase.LoginAsTenant(String tenancyName, String userName) in aspnetboilerplate-core-entityframework6\\aspnet-core\\test\\AbpCompanyName.AbpProjectName.Tests\\AbpProjectNameTestBase.cs:line 241
in AbpCompanyName.AbpProjectName.Tests.AbpProjectNameTestBase.LoginAsDefaultTenantAdmin() in aspnetboilerplate-core-entityframework6\\aspnet-core\\test\\AbpCompanyName.AbpProjectName.Tests\\AbpProjectNameTestBase.cs:line 212
in AbpCompanyName.AbpProjectName.Tests.AbpProjectNameTestBase..ctor() in aspnetboilerplate-core-entityframework6\\aspnet-core\\test\\AbpCompanyName.AbpProjectName.Tests\\AbpProjectNameTestBase.cs:line 55
in AbpCompanyName.AbpProjectName.Tests.Users.UserAppService_Tests..ctor() in aspnetboilerplate-core-entityframework6\\aspnet-core\\test\\AbpCompanyName.AbpProjectName.Tests\\Users\\UserAppService_Tests.cs:line 15
So the problem is that in Abp.Authorization.Users.AbpUser the constructor is initializing the collection Tokens as a new Collection of UserTokens, see code below:
protected AbpUser()
{
Tokens = new Collection<UserToken>();
}
When EF6 lazy loading tries to initialize that collection with its virtual collection wrapper, it throws an exception beacuse that property is already initialized, so you need to find a solution to have lazy loading to work properly.
Summary
Those errors are preventing a vanilla ASP.NET Boilerplate application to work properly when using the ZeroCore module and EntityFramework 6 at the same time. I will consider this as fixed as soon the sample project I created starts working just by updating the referenced nuget packages to the fixed versions.
I think the most appropiate people I should mention here are: @ryancyq @acjh and @hikalkan
Best regards, Emiliano.
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (6 by maintainers)
Top GitHub Comments
Thanks, I was able to reproduce that.
Fixed by #2841