Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SaveChanges() throw exception, using OwnsOne in OnModelCreating() when initialize database #10578

Closed
hanslai opened this issue Dec 16, 2017 · 2 comments

Comments

@hanslai
Copy link

hanslai commented Dec 16, 2017

An aggregateRoot class

public class Testcalss
    {
        public int Id { get; protected set; }
        public string Name { get; private set; }
        public string Description { get; private set; }
        public Address HomeAddress { get; private set; }

        private Testcalss()    {   }

        public static Testcalss Create(string name, string description)
        {
            return new Testcalss
            {
                Name = name,
                Description = description,
            };
        }
    }

A value object class

public class Address : ValueObject
{
        public string Country { get; private set; }
        public string ProvinceOrState { get; private set; }
        public string City { get; private set; }
        public string Street { get; private set; }
        public string Zipcode { get; private set; }

        private Address() { }
        public Address(string country = "", string provinceOrState = "", string city = "", string street = "", string zipcode = "")
        {
            Country = country;
            ProvinceOrState = provinceOrState;
            City = city;
            Street = street;
            Zipcode = zipcode;
        }
}

OnModelingCreating

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Testcalss>().HasKey(x => x.Id);
            modelBuilder.Entity<Testcalss>().OwnsOne(x => x.HomeAddress);
            base.OnModelCreating(modelBuilder);
        }

Full exceptions details (message and stack trace).

System.InvalidOperationException
  HResult=0x80131509
  Message=**The entity of 'Testcalss' is sharing the table 'Testcalss' with 'Testcalss.HomeAddress#Address', but there is no entity of this type with the same key value that has been marked as 'Added'.** Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the key values.
  Source=Microsoft.EntityFrameworkCore.Relational
  StackTrace:
   at Microsoft.EntityFrameworkCore.Update.Internal.ModificationCommandIdentityMap.Validate(Boolean sensitiveLoggingEnabled)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.CreateModificationCommands(IReadOnlyList`1 entries, Func`1 generateParameterName)
   at Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.<BatchCommands>d__8.MoveNext()
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(Tuple`2 parameters)
   at Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation)
   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
   at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList`1 entries)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
   at AIS.SharedKernel.Data.CommonDbContext.SaveChanges() in c:\Source\Repos\AIS\AIS.SharedKernel\Data\CommonDbContext.cs:line 42
   at AIS.HR.Data.Services.DatabaseInitializer.SeedTestDatabase(HRContext context) in c:\Source\Repos\AIS\AIS.HR\AIS.HR.Data\Services\DatabaseInitializer.cs:line 94
   at AIS.HR.API.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, HRContext hrContext) in c:\Source\Repos\AIS\AIS.HR\AIS.HR.API\Startup.cs:line 95

Steps to reproduce

It is a asp.net core project, when initialize database in Startup class' Configure method with the following code.

            Testcalss t1 = Testcalss.Create("name1", "Desc1", 1);
            Testcalss t2 = Testcalss.Create("name2", "Desc2", 2);
            var testdata = new Testcalss[] { t1, t2 };
            context.AddRange(testdata);
            context.SaveChanges();

SaveChanges throw InvalidOperationExcetion.

Further technical details

EF Core version: Microsoft.AspNetCore.All Version="2.0.3"
Database Provider: (localdb)\mssqllocaldb
Operating system: Windows 10
IDE: (Visual Studio 2017 15.5.2)

@Tarig0
Copy link

Tarig0 commented Dec 16, 2017

You have to set the address property to an instance of the owned enitity.

@hanslai
Copy link
Author

hanslai commented Dec 16, 2017

@Tarig0 Thanks, it make sense.
At the same time, it feels unnatural. For example, if Address’ parent entity is an Employee, then I have to set the Address of that employee when I create an Employee class. Maybe I need to rethink my model.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants