EF例外,如何首先在C#和实体框架代码中为地址建模

迈克尔·唐奇达(Michael Tranchida)

EF引发以下异常:

System.InvalidOperationException:引用完整性约束冲突。从属角色具有多个具有不同值的主体。

我有两个实体,即StateProvince和Country:

public class StateProvince
{
    public long Id { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    public long CountryId { get; set; }
    public Country Country { get; set; }
}

public class Country
{
    public long Id { get; set; }

    [StringLength(2)]
    public string Code { get; set; }

    public IEnumerable<StateProvince> StatesProvinces { get; set; }
}

和两个使用它们的实体:

public class Customer
{
    public long Id { get; set; }

    public long BillingStateProvinceId { get; set; }
    [ForeignKey("Id")]
    public StateProvince BillingStateProvince { get; set; }

    public long BillingCountryId { get; set; }
    [ForeignKey("Id")]
    public Country BillingCountry { get; set; }

    public long ShippingStateProvinceId { get; set; }
    [ForeignKey("Id")]
    public StateProvince ShippingStateProvince { get; set; }

    public long ShippingCountryId { get; set; }
    [ForeignKey("Id")]
    public Country ShippingCountry { get; set; }
}

public class Vendor
{
    public long Id { get; set; }

    public long StateProvinceId { get; set; }
    public StateProvince StateProvince { get; set; }

    public long CountryId { get; set; }
    public Country Country { get; set; }
}

在我的OnModelCreating中:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.ShippingStateProvince)
            .WithOptional().WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.ShippingCountry)
            .WithOptional().WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.BillingStateProvince)
            .WithOptional().WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.BillingCountry)
            .WithOptional().WillCascadeOnDelete(false);

        modelBuilder.Entity<Vendor>()
            .HasRequired(m => m.StateProvince)
            .WithOptional().WillCascadeOnDelete(false);

        modelBuilder.Entity<Vendor>()
            .HasRequired(m => m.Country)
            .WithOptional().WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }

最后,引发异常的代码:

[TestMethod]
    public void TestMethod1()
    {
        Db db = new Db();

        #region Set/reset items

        Country us = db.Countries.FirstOrDefault();
        if (us == null)
        {
            us = new Country { Code = "US" };
            db.Countries.Add(us);
            db.SaveChanges();
        }
        long usId = us.Id;

        List<StateProvince> states = db.StateProvinces.ToList();
        StateProvince mass = states.Where(m => m.Name == "MA").FirstOrDefault();
        StateProvince ct = states.Where(m => m.Name == "CT").FirstOrDefault();
        if (mass == null)
        {
            mass = new StateProvince { Name = "MA", CountryId = usId };
            ct = new StateProvince { Name = "CT", CountryId = usId };
            db.StateProvinces.Add(mass);
            db.StateProvinces.Add(ct);
            db.SaveChanges();
        }
        long massId = mass.Id;
        long ctId = ct.Id;

        List<Customer> customersToRemove = db.Customers.ToList();
        db.Customers.RemoveRange(customersToRemove);
        db.SaveChanges(); 

        #endregion

        Customer customerToAdd = new Customer { 
            BillingStateProvinceId = massId, 
            ShippingStateProvinceId = ctId, 

            ShippingCountryId = usId, 
            BillingCountryId = usId,

            BillingStateProvince = mass,
            ShippingStateProvince = ct,

            BillingCountry = us,
            ShippingCountry = us
        };

        db.Customers.Add(customerToAdd);

        try
        {
            //exception thrown here
            db.SaveChanges();
        }
        catch (Exception e)
        {
            throw;
        }

        db.Dispose();

        Db dbCheck = new Db();

        Customer customer = dbCheck.Customers.Include(m => m.BillingStateProvince).Include(m => m.ShippingStateProvince).FirstOrDefault();

        dbCheck.Dispose();
    }

我怀疑问题是我没有正确使用[ForeignKey]属性,还是我在OnModelCreating中做错了什么。如果我在客户实体中只有一个StateProvince和一个Country实体,则可以使它工作,但是,一旦有两个,就无法解决。有什么帮助吗?

从更广泛的角度来看,没有人链接到博客/帖子/文章/教程,这些链接涉及如何首先使用c#EF代码对地址进行建模?我碰到了一个使用[ComplexType]属性的应用程序,问题是我无法在其中封装StateRegion和Country类。我目前的想法是将每个类的各个地址字段都烘烤,即MailingStreetAddress,BillingStreetAddress等。我想看看其他人如何处理地址,以更好地理解自己的地址。

编辑

我是@@ Sam,我尝试将属性更改为:

[ForeignKey("BillingStateProvinceId")]

每个属性。删除/重新创建数据库后,EF抛出此错误:

Customer_BillingCountry_Source::多重性在关系“ Customer_BillingCountry”中的角色“ Customer_BillingCountry_Source”中无效。由于从属角色属性不是关键属性,因此从属角色多重性的上限必须为'。Customer_BillingStateProvince_Source ::多重性在关系“ Customer_BillingStateProvince”中的角色“ Customer_BillingStateProvince_Source”中无效。由于从属角色属性不是关键属性,因此从属角色多重性的上限必须为''。Customer_ShippingCountry_Source::多重性在关系“ Customer_ShippingCountry”中的角色“ Customer_ShippingCountry_Source”中无效。由于从属角色属性不是关键属性,因此从属角色多重性的上限必须为'。Customer_ShippingStateProvince_Source::多重性在关系“ Customer_ShippingStateProvince”中的角色“ Customer_ShippingStateProvince_Source”中无效。由于从属角色属性不是关键属性,因此从属角色多重性的上限必须为'。

编辑2

对于每个@Steve Green,更改了我的StateRegion,Country实体和OnModelCreating,现在当我删除重新创建db时会引发此错误:

指定的架构无效。错误:由于类型“ StackOverflow.Country”不可用,因此未加载关系“ StackOverflow.Customer_ShippingCountry”。

我编辑的代码:

public class StateProvince
{
    public long Id { get; set; }

    [StringLength(100)]
    public string Name { get; set; }

    //new properties
    public ICollection<Customer> Customers { get; set; }
    public ICollection<Vendor> Vendors { get; set; }

    public long CountryId { get; set; }
    public Country Country { get; set; }
}

public class Country
{
    public long Id { get; set; }

    [StringLength(2)]
    public string Code { get; set; }

    //new properties
    public ICollection<Customer> Customers { get; set; }
    public ICollection<Vendor> Vendors { get; set; }

    public IEnumerable<StateProvince> StatesProvinces { get; set; }
}

而我的OnModelCreating反映了他的观点:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.ShippingStateProvince)
            .WithMany(m => m.Customers)
            .HasForeignKey(m => m.ShippingStateProvinceId);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.ShippingCountry)
            .WithMany(m => m.Customers)
            .HasForeignKey(m => m.ShippingCountryId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.BillingStateProvince)
            .WithMany(m => m.Customers)
            .HasForeignKey(m => m.BillingStateProvinceId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.BillingCountry)
            .WithMany(m => m.Customers)
            .HasForeignKey(m => m.BillingCountryId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Vendor>()
            .HasRequired(m => m.StateProvince)
            .WithMany(m => m.Vendors)
            .HasForeignKey(m => m.StateProvinceId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Vendor>()
            .HasRequired(m => m.Country)
            .WithMany(m => m.Vendors)
            .HasForeignKey(m => m.CountryId)
            .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }
史蒂夫·格林

由于您已经有了流畅的配置,因此可以进行如下操作并放弃注释:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.StateProvince)
            .WithMany() 
            .HasForeignKey(c => c.ShippingStateProvinceId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.Country)
            .WithMany() 
            .HasForeignKey(c => c.ShippingCountryId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.StateProvince)
            .WithMany() 
            .HasForeignKey(c => c.BillingStateProvinceId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Customer>()
            .HasRequired(m => m.Country)
            .WithMany() 
            .HasForeignKey(c => c.BillingCountryId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Vendor>()
            .HasRequired(m => m.StateProvince)
            .WithMany() 
            .HasForeignKey(c => c.StateProvinceId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Vendor>()
            .HasRequired(m => m.StateProvince)
            .WithMany() 
            .HasForeignKey(c => c.CountryId)
            .WillCascadeOnDelete(false);


        base.OnModelCreating(modelBuilder);
    }

https://msdn.microsoft.com/zh-CN/data/jj591620.aspx#Model

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何首先在Wicket中呈现<meta>标签?

首先在实体框架代码中为同一表定义多个外键

如何首先在EF6代码中设置唯一属性

如何首先在EF 7代码中使用数据注释指定唯一键

首先在实体框架集列中编写代码以在SQL Server中键入datetime2

实体框架数据库首先在dll上出现异常行为

如何首先在实体框架代码中用户“合并”以将存储过程中的多个结果集合并到一个单个集合中

多个外键EF Core 2.1代码首先在数据库中仅生成1

如何首先在Entity Framework代码中为Identity主键设置起始值?

如何从首先在php中重新启动循环

如何首先在asp.net核心中的代码中创建关系

首先在EF6代码中创建多对多关系

首先在EF代码中设计一对多关系的最佳实践

首先在EF代码中删除列

实体框架Powertools-代码首先在生成时生成视图

首先在Entity Framework代码中链接子表

如何首先在EF代码中建立模型与枚举之间的多对多关系?

首先在实体框架代码中初始化数据库中的对象

如何首先在代码中获得具有外键关系的子实体中的父实体属性?

EF代码首先在我定义的代码旁边添加它自己的FK

如何强制弹簧数据首先在缓存中,然后在数据源中,然后才在缓存中为CrudRepository的findAll方法查找实体

如何首先在实体框架6代码中创建可为空的一对多关系

为什么实体框架数据库首先在删除时覆盖无操作

如何首先在实体框架代码中的 linq 中使用可为空列表?

首先在实体框架代码中,要映射导航属性是否还需要映射外键列

如何首先在代码中定义两个实体之间的多对多和一对多关系?

c# - 如何通过实体框架代码的流畅API首先在c#中更改表名?

首先在实体框架数据库中调用存储过程 - 结果类中的列生成问题

如何首先在代码中保存外键的集合