简体   繁体   English

我可以对带有实体框架6的Seed方法操作使用foreach循环-Update-Database命令

[英]Can I use a foreach loop on Seed method operations with Entity Framework 6 - Update-Database command

Mainly I'm trying to insert all cities data coming from an Xml using a foreach loop to iterate through each state. 主要是我试图使用foreach循环插入来自Xml的所有城市数据以遍历每个州。 We have more than 5000 city records, and this was the only approach I could come up with. 我们有5000多个城市记录,这是我唯一能想到的方法。

  // Cities Seeding foreach (var uf in Enum.GetValues(typeof(Uf))) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load("http://servicos.cptec.inpe.br/~rserv/estados/cidade-" + uf.ToString() + ".xml"); int cityId = Convert.ToInt32(xmlDoc.SelectSingleNode("/climas/clima/estados/estado/cidades/cidade").Attributes["id"].Value); string cityName = xmlDoc.SelectSingleNode("/climas/clima/estados/estado/cidades/cidade").Attributes["nome"].Value.ToString(); bool capital = Convert.ToBoolean(xmlDoc.SelectSingleNode("/climas/clima/estados/estado/cidades/cidade").Attributes["capital"].Value); int stateId = 1; //if (!capital) //{ context.Cities.AddOrUpdate( c => c.CityId, new City { CityId = cityId, CityName = cityName, StateId = stateId }); //} //else //{ //context.Capitals.AddOrUpdate( // cp => cp.CityId, // new Capital // { // CityId = cityId, // CityName = cityName, // StateId = stateId // }); //} stateId++; } 

I'm not sure if makes any difference in this case but, State Id is a foreign key from States Table. 我不确定在这种情况下是否有任何区别,但是State ID是States表中的外键。

This is my error message: 这是我的错误信息:

System.Data.Entity.Infrastructure.DbUpdateException: An error occurred while updating the entries. System.Data.Entity.Infrastructure.DbUpdateException:更新条目时发生错误。 See the inner exception for details. 有关详细信息,请参见内部异常。 ---> System.Data.Entity.Core.UpdateException: An error occurred while updating the entries. ---> System.Data.Entity.Core.UpdateException:更新条目时发生错误。 See the inner exception for details. 有关详细信息,请参见内部异常。 ---> Npgsql.NpgsqlException: ERROR: 23503: insert or update on table "City" violates foreign key constraint "FK_public.City_public.States_StateId" ---> Npgsql.NpgsqlException:错误:23503:在表“ City”上插入或更新违反了外键约束“ FK_public.City_public.States_StateId”

An error occurred while updating the entries. 更新条目时发生错误。 See the inner exception for details. 有关详细信息,请参见内部异常。

Like @Sirwan said, the exception you are seeing is telling you that you are violating the foreign key constraint to the states table. 就像@Sirwan所说的那样,您所看到的异常情况是告诉您您违反了states表的外键约束。 Judging by the FK name, it looks like you are using a stateId value that doesn't exist in the States table 从FK名称来看,您似乎使用的是States表中不存在的stateId

insert or update on table "City" violates foreign key constraint "FK_public.City_public.States_StateId 在表“ City”上进行插入或更新违反了外键约束“ FK_public.City_public.States_StateId

You also said: 您还说过:

State Id is a foreign key from States Table 状态ID是国家表中的外键

So, I'm assuming that the States table is a pre-populated table with the state records already in it. 因此,我假设“状态”表是一个预先填充的表,其中已经有“状态”记录。 In other words, the states are not being inserted based on the XML file. 换句话说,不会基于XML文件插入状态。 Is that the case? 是这样吗

Your code also makes two main assumptions: 您的代码也有两个主要假设:

  1. It assumes that the number of items in the Uf enum is less than or equal to the number of records in the States table. 它假定,在项目的数量Uf枚举小于或等于在记录数States表。

  2. It assumes that the items in the Uf enum are sorted matching the records in the States table sorted by StatedId ascending. 假定Uf枚举中的项目与按StatedId升序排序的States表中的记录匹配。

If assumption 1 is invalid, ie you have more records in the Uf enum than you have in the States table, you will try to insert records using a stateId that doesn't exist. 如果假设1无效,即Uf枚举中的记录多于States表中的记录,则将尝试使用不存在的stateId插入记录。

if assumption 2 is invalid, ie the Uf enum elements are not sorted matching the stateId in the States table, you will insert the cities to the wrong state. 如果假设2无效,即Uf枚举元素未与States表中的stateId匹配,则您会将城市插入错误的状态。

Based on the exception you posted, I bet that assumption 1 is invalid, that the number of records on the Uf enum doesn't match the number of records in the States table. 根据您发布的例外,我敢打赌,假设1是无效的,将记录在数Uf枚举不匹配的记录数States表。 Or, the other option is that the StateId values in the States table doesn't match the raw number of elements in the enum. 或者,另一种选择是, StateId中的值States表不匹配的枚举元素的原料数量。

For example, I saw that you are from Brasil, where we have 27 states. 例如,我看到您来自巴西,那里有27个州。 Here we have three options for your error: 在这里,我们为您的错误提供了三种选择:

  1. States table doesn't have all the 27 states States表没有全部27个州
  2. The StateId values in the States table don't start from 1 States表中的StateId值不是从1开始
  3. The StateId values in the States table are not contiguous, ie they don't go from 1-27 but have gaps like : 1,2,3,6,7,8,9 ... StateId中的值States表是不连续的,即它们不从1-27去,但有差距,如: 1,2,3,6,7,8,9 ...

In all the scenarios above, your code would end up using an invalid stateId that will violate the FK constraint. 在上述所有情况下,您的代码最终都将使用无效的stateId ,这将违反FK约束。

The less brittle way to write this code, while possibly paying a small performance tax, would be iterate over the values of the State table instead of using the Uf enum. 编写此代码的方法不太灵活,尽管可能要缴纳少量的性能税,但会遍历State表的值,而不是使用Uf枚举。 That way, you can make sure that the StateId value that you are assigning to the record matches the one from the table: 这样,您可以确保分配给记录的StateId值与StateId值匹配:

foreach (var state in context.States)
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load("http://servicos.cptec.inpe.br/~rserv/estados/cidade-" + state.Name + ".xml");
    int cityId = Convert.ToInt32(xmlDoc.SelectSingleNode("/climas/clima/estados/estado/cidades/cidade").Attributes["id"].Value);
    string cityName = xmlDoc.SelectSingleNode("/climas/clima/estados/estado/cidades/cidade").Attributes["nome"].Value.ToString();

    context.Cities.AddOrUpdate(
        c => c.CityId,
        new City
        {
            CityId = cityId,
            CityName = cityName,
            StateId = state.StateId
        });
}

This error is telling you that you are violating the foreign key constraint. 此错误表明您违反了外键约束。 Check that there is not existing data in the database that is conflicting with the FK constraint causing the creation to fail. 检查数据库中是否没有与FK约束冲突的数据,从而导致创建失败。

One more thing : Why do you increment the stateId ? 还有一件事 :为什么要增加stateId As you mentioned you have more than 5000 city records, So the State table must contains more than records too. 正如您提到的,您有5000多个城市记录,因此State表也必须包含多个记录。

This is how my code looked in the end: 这是我的代码最终的外观:

context.SaveChanges();

    //Cities Seeding
    int stateId = 1;
    foreach (var uf in Enum.GetValues(typeof(Uf)))
    {

        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load("http://servicos.cptec.inpe.br/~rserv/estados/cidade-" + uf.ToString() + ".xml");
        XmlElement root = xmlDoc.DocumentElement;
        XmlNodeList nodes = root.SelectNodes("/climas/clima/estados/estado/cidades/cidade");
        foreach (XmlNode node in nodes)
        {
            int cityId = Convert.ToInt32(node.Attributes["id"].Value);
            string cityName = node.Attributes["nome"].Value.ToString();
            bool cityIsCapital = Convert.ToBoolean(node.Attributes["capital"].Value);
            context.Cities.AddOrUpdate(
            c => c.CityId,
            new City()
            {
                CityId = cityId,
                CityName = cityName,
                CityIsCapital = cityIsCapital,
                StateId = stateId
            });
        }
        stateId++;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在实体框架6的更新数据库上未调用Seed方法 - Seed method is not called on update-database, Entity Framework 6 实体框架5.0(C#):仅在两次运行更新数据库时,才运行种子方法 - Entity Framework 5.0 (C#): Seed method only run if Update-Database is run twice 实体框架 - ConnectionProviderName的Update-database命令提示 - Entity Framework - Update-database Command Prompting for ConnectionProviderName 实体框架核心 - “更新数据库”不起作用 - Entity Framework Core - 'Update-Database' not working 带有-ConnectionString的实体框架更新数据库 - Entity Framework Update-Database with -ConnectionString 实体框架6中“更新数据库”之后发生错误 - Error after 'update-database' in Entity Framework 6 如何使用 pm> Update-Database 命令? - how to use pm> Update-Database command? Entity Framework 6, Update-Database -verbose 命令没有构建正确的文件路径来保存我的 mdf 文件 - Entity Framework 6, Update-Database -verbose command is not constructing the correct filepath to save my mdf file 实体框架代码第一次更新 - 数据库在CREATE DATABASE上失败 - Entity Framework code first update-database fails on CREATE DATABASE Entity Framework Core 不在更新数据库上创建数据库 - Entity Framework Core not creating database on update-database
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM