You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Dec 14, 2017. It is now read-only.
I will explain the bug and then a simple work-a-round.
The old Issue is a valid bug. But the bug isn't coming from the fact that @corpsekicker was creating a custom User Account. The bug is coming from the fact that DbContextUserAccountRepository's
public override TAccount Create()
{
return items.Create();
}
is called.
This call is triggered when CreateAccount is called where the account parameter is set to null. Thus, when the following code is called
account = account ?? CreateUserAccount();
the CreateUserAccount() is executed. Which eventually calls into DbContextUserAccountRepository's
public override TAccount Create()
{
return items.Create();
}
Note that items is defined as a DbSet<TAccount>, therefore, this call creates a User Account proxy which is already associated with EF.
Then when
userRepository.Add(account);
is called (a few lines after the account = account ?? CreateUserAccount(); line), the DbModelBuilderExtensions.RegisterUserAccountChildTablesForDelete(...) is triggered. Which runs this set of code
Because the account is 'known' by EF (and is marked at 'added') then none of the account's collections can be de-referenced. If they are de-referenced, as in account.ClaimCollection, then EF throws the following exception
The source query for this EntityCollection or EntityReference cannot be returned when the related object is in either an added state or a detached state and was not originally retrieved using the NoTracking merge option.
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.CreateSourceQuery[TEntity](MergeOption mergeOption, Boolean& hasResults)
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.ValidateLoad[TEntity](MergeOption mergeOption, String relatedEndName, Boolean& hasResults)
at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption)
at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()
at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)
at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.b__1(TProxy proxy, TItem item)
at System.Data.Entity.DynamicProxies.UserAccount_4D648538DA59C57D93498042CF9A88749A46F5408DCB6BFA60F620357F905DE6.get_ClaimCollection()
at System.Data.Entity.DbModelBuilderExtensions.<>c__DisplayClass1`8.b__0(Object sender, NotifyCollectionChangedEventArgs e) in c:\\SW\\3rdParty\\ThinkTecture\\MembershipReboot\\BrockAllen.MembershipReboot-master\\src\\BrockAllen.MembershipReboot.Ef\\DbModelBuilderExtensions.cs:line 33
...
The good news - this bug is easy to work-a-round.
The Work-a-Round
Call CreateAccount with an existing account. For example
_userAccountService.CreateAccount(username, password, email, account: new UserAccount());
So, when the account.ClaimCollection is de-reference the value is null and the extension method works without complaining. Thus everything works just fine.
Happy Coding!
The text was updated successfully, but these errors were encountered:
I just go the same issue with trying to create a Group, and I'm currently block on this issue.
I think you might be right, that perhaps the EF logic should be changed to calling 'new'.Otherwise, I don't think any of the RegisterXXXXXForDelete will work as expected.
Or perhaps just change:
public override TGroup Create()
{
return items.Create();
}
to
public override TGroup Create()
{
return items.AsNoTracking().Create();
}
So that the new item isn't being tracked, I'm testing it now. I'll let you know what I find.
The Bug
I will explain the bug and then a simple work-a-round.
The old Issue is a valid bug. But the bug isn't coming from the fact that @corpsekicker was creating a custom User Account. The bug is coming from the fact that DbContextUserAccountRepository's
is called.
This call is triggered when CreateAccount is called where the
account
parameter is set to null. Thus, when the following code is calledthe CreateUserAccount() is executed. Which eventually calls into DbContextUserAccountRepository's
Note that
items
is defined as aDbSet<TAccount>
, therefore, this call creates a User Account proxy which is already associated with EF.Then when
is called (a few lines after the
account = account ?? CreateUserAccount();
line), theDbModelBuilderExtensions.RegisterUserAccountChildTablesForDelete(...)
is triggered. Which runs this set of codeBecause the
account
is 'known' by EF (and is marked at 'added') then none of the account's collections can be de-referenced. If they are de-referenced, as inaccount.ClaimCollection
, then EF throws the following exceptionThe good news - this bug is easy to work-a-round.
The Work-a-Round
Call
CreateAccount
with an existingaccount
. For exampleSo, when the
account.ClaimCollection
is de-reference the value isnull
and the extension method works without complaining. Thus everything works just fine.Happy Coding!
The text was updated successfully, but these errors were encountered: