[英]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: 您的代码也有两个主要假设:
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
表。
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: 在这里,我们为您的错误提供了三种选择:
States
table doesn't have all the 27 states States
表没有全部27个州 StateId
values in the States
table don't start from 1 States
表中的StateId
值不是从1开始 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.