简体   繁体   中英

EF7 beta5: Error trying to insert child entity

I have created an API using ASP.NET5 and Entity Framework 7.0.0-beta 5.

I have the Model, DbContext and the Repository created as is described here , and when I try to insert data with a child entity my app throw an exception:

"Cannot insert the value NULL into column 'Status', table 'Company'; column does not allow nulls. INSERT fails."

代码+异常

The Status attribute is not null in my Company entity, but I don't know why EF is not capable of insert the value of the child entity. (in this case, "1")

This is the stack trace:

   at Microsoft.Data.Entity.Relational.Update.ReaderModificationCommandBatch.Execute(RelationalTransaction transaction, IRelationalTypeMapper typeMapper, DbContext context, ILogger logger)
   at Microsoft.Data.Entity.Relational.Update.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
   at Microsoft.Data.Entity.Relational.RelationalDataStore.SaveChanges(IReadOnlyList`1 entries)
   at Microsoft.Data.Entity.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
   at Microsoft.Data.Entity.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.Data.Entity.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.Data.Entity.DbContext.SaveChanges()
   at **.Data.Repositories.CompanyRepository.Create(Company company) in D:\**.Data\Repositories\CompanyRepository.cs:line 36
   at **.API.Controllers.CompanyController.Create(Company company) in D:\**.API\Controllers\CompanyController.cs:line 48

Here is the code:

DbContext

public class MrBellhopContext : DbContext
{

    public DbSet<Company> Company { get; set; }
    public DbSet<CompanyStatus> CompanyStatus { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Company>().Table("Company");
        modelBuilder.Entity<Company>().Key(c => c.CompanyId);
        modelBuilder.Entity<Company>().Index(c => c.Name);
        modelBuilder.Entity<Company>().Reference(c => c.Status).InverseReference().ForeignKey<CompanyStatus>(cs => cs.StatusId);

        modelBuilder.Entity<CompanyStatus>().Table("CompanyStatus");
        modelBuilder.Entity<CompanyStatus>().Key(cs => cs.StatusId);

        base.OnModelCreating(modelBuilder);
    }

}

Model

public class Company
{

    public int CompanyId { get; set; }

    public string Name { get; set; }

    public string Email { get; set; }

    public CompanyStatus Status { get; set; }

    public DateTime CreatedAt { get; set; }

    public DateTime UpdatedAt { get; set; }

}

public class CompanyStatus
{

    public int StatusId { get; set; }

    public string Name { get; set; }

}

Repository (only create method)

    public int Create(Company company)
    {
        _dbcontext.Add(company);
        _dbcontext.SaveChanges();

        return company.CompanyId;
    }

Does anyone know how to insert correctly child entities?

Try to change Repository method to :

public int Create(Company company)
{
    using (MyDbcontextdbcontext context = new MyDbcontext()) 
    { 
        context.Entry(company).State = EntityState.Added; 
        context.SaveChanges(); 
    }
}

More information : https://msdn.microsoft.com/en-us/data/jj592676.aspx

The model configuration is incorrect. This is attempting to configure the foreign key for Company by pointing to a property on CompanyStatus . Foreign Keys must be a property on Company .

Also, InverseReference() is for one-to-one relationships. It appears this is trying to get a one-to-many, so use InverseCollection() instead.

Two solutions

(This assumes the schema is correctly setup to use foreign keys).

  1. Add a CLR property to Company that contains StatusId. The configuration line should be changed to

modelBuilder.Entity<Company>() .Reference(c => c.Status) .InverseCollection() .ForeignKey(cs => cs.StatusId);

  1. If you don't want StatusId in the CLR type, then configure a shadow state property.

modelBuilder.Entity<Company>(b=>{ b.Property<int>("StatusId"); //this configures the shadow property b.Reference(c => c.Status).InverseCollection().ForeignKey("StatusId"); });

In EF7, you need to have your child object attached into the context. This is different from EF6, and I'm pretty sure is the scenario you are facing. Try to attach the object to the dbcontext before saving.

happened to me, check out this Issue : https://github.com/aspnet/EntityFramework/issues/2387 for more information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM