INSERT语句与FOREGIGN KEY约束冲突

时间:2017-02-27 18:18:24

标签: asp.net entity-framework entity-framework-core

我是一名绿色的asp.net开发人员,我在项目中使用最新的实体框架。我有一个问题是使用自动生成的值来播种我的数据库(我认为)。这是确切的错误。

enter image description here

以下是代码:

public class Address
{
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int AddressId { get; set; }
// some more properties
}

public class ApplicationUser : IdentityUser
{
        [ForeignKey("Address")]        
    public int AddressId { get; set; }
    public Address Address { get; set; }

// some more properties
}

public class Shelter
{
        [Required]
        [ForeignKey("Address")]
        public int AddressId { get; set; }
        public Address Address { get; set; }
// some more properties
}
//seed
private void CreateShelters()
{
    EntityEntry<Address> MspcaAddress = DbContext.Addresses.Add(new Address()
    {
                Street = "350 S Huntington Ave",
                City = "Jamaica Plain",
                State = "MA",
                AreaCode = "02130",
                Latitude = 42.3228928,
                Longititude = -71.11120540000002
    });
     EntityEntry<Address> BostonAnimalCareAndControlAddress = DbContext.Addresses.Add(new Address()
     {
                Street = "26 Mahler Rd",
                City = "Roslindale",
                State = "MA",
                AreaCode = "02131",
                Latitude = 42.2943377,
                Longititude = -71.12153390000003
            });
            EntityEntry<Address> AnimalRescueLeagueOfBostonAddress = DbContext.Addresses.Add(new Address()
            {
                Street = "10 Chandler St",
                City = "Boston",
                State = "MA",
                AreaCode = "0S2116",
                Latitude = 42.3470486,
                Longititude = -71.06976929999996
            });

            EntityEntry<Shelter> Mspca = DbContext.Shelters.Add(new Shelter()
            {
                Name = "MCSPA",
                AddressId = MspcaAddress.Entity.AddressId
            });
            EntityEntry<Shelter> BostonAnimalCareAndControl = DbContext.Shelters.Add(new Shelter()
            {
                Name = "Boston Animal Care And Control",
                AddressId = BostonAnimalCareAndControlAddress.Entity.AddressId
            });
            EntityEntry<Shelter> AnimalRescueLeagueOfBoston = DbContext.Shelters.Add(new Shelter()
            {
                Name = "Animal Rescue League Of Boston Address",
                AddressId = AnimalRescueLeagueOfBostonAddress.Entity.AddressId
            });
            DbContext.SaveChanges();
   }

我尝试重新创建数据库以查看数据/表格是否存在问题,但我仍然遇到错误。有什么想法吗?

2 个答案:

答案 0 :(得分:4)

您尝试播种的“Shelter”实体要求您提交现有的AddressID上面的代码,尝试获取尚未创建的地址的AddressId。< / p>

您必须先将地址提交到数据库(使用DbContext.SaveChanges();

然后,您可以使用检索到的AddressId创建Shelter实体。下面的代码显示了如何执行此操作的示例,但您可能必须重新编写获取addressId的查询。或者,您可能必须将它们与插入过程完全分开。

    private void CreateShelters()
{
    EntityEntry<Address> MspcaAddress = DbContext.Addresses.Add(new Address()
    {
                Street = "350 S Huntington Ave",
                City = "Jamaica Plain",
                State = "MA",
                AreaCode = "02130",
                Latitude = 42.3228928,
                Longititude = -71.11120540000002
    });
     EntityEntry<Address> BostonAnimalCareAndControlAddress = DbContext.Addresses.Add(new Address()
     {
                Street = "26 Mahler Rd",
                City = "Roslindale",
                State = "MA",
                AreaCode = "02131",
                Latitude = 42.2943377,
                Longititude = -71.12153390000003
            });
            EntityEntry<Address> AnimalRescueLeagueOfBostonAddress = DbContext.Addresses.Add(new Address()
            {
                Street = "10 Chandler St",
                City = "Boston",
                State = "MA",
                AreaCode = "0S2116",
                Latitude = 42.3470486,
                Longititude = -71.06976929999996
            });

    DbContext.SaveChanges();


            EntityEntry<Shelter> Mspca = DbContext.Shelters.Add(new Shelter()
            {
                Name = "MCSPA",
                AddressId = MspcaAddress.Entity.AddressId
            });
            EntityEntry<Shelter> BostonAnimalCareAndControl = DbContext.Shelters.Add(new Shelter()
            {
                Name = "Boston Animal Care And Control",
                AddressId = DbContext.Addresses.Where(x => x.Street == "26 Mahler Rd").FirstOrDefault().AddressId
       });
            EntityEntry<Shelter> AnimalRescueLeagueOfBoston = DbContext.Shelters.Add(new Shelter()
            {
                Name = "Animal Rescue League Of Boston Address",
                AddressId = DbContext.Addresses.Where(x => x.Street == "10 Chandler St").FirstOrDefault().AddressId

            });
            DbContext.SaveChanges();
   }

希望这足以让你过去。如果对addressId的查询不起作用,请告诉我,我将很乐意帮助您解决这些问题。

答案 1 :(得分:2)

这个问题的关键:)是使用引用属性而不是Id值。这意味着:设置Address而不是AddressId。当EF保存更改时,它将确定实体之间的依赖关系,并以正确的顺序保存它们,同时将生成的AddressId键值及时设置为外键值。

您的代码的本质(即为了简洁而省略了财产分配)应如下所示:

var mspcaAddress = new Address();
var bostonAnimalCareAndControlAddress = new Address();
var animalRescueLeagueOfBostonAddress = new Address();
context.Addresses.AddRange(new[]
{
    mspcaAddress,
    bostonAnimalCareAndControlAddress,
    animalRescueLeagueOfBostonAddress
});

var mspca = new Shelter()
{
    Address = mspcaAddress
};
var bostonAnimalCareAndControl = new Shelter()
{
    Address = bostonAnimalCareAndControlAddress
};
var animalRescueLeagueOfBoston = new Shelter()
{
    Address = animalRescueLeagueOfBostonAddress
};
context.Shelters.AddRange(new[]
{
    mspca,
    bostonAnimalCareAndControl,
    animalRescueLeagueOfBoston
});
context.SaveChanges();

虽然您显示的错误适用于AddressId中的ApplicationUser,但我认为创建ApplicationUser的类似方法可以解决此问题。

顺便说一句,你可以不用第一个context.Addresses.AddRange语句。地址将通过添加避难所来添加。

请注意,我还从代码中删除了EntityEntry。我认为他们不必要地使代码复杂化。您只需要创建的简单对象。