我试图写一个程序来扫描包含电视节目的文件夹目录,查找有关使用tvrage API的节目的一些细节,然后使用实体框架的细节保存到数据库DB。实体框架插入错误的实体插入的SaveChanges
我TVShow表p键是相同的值从tvrage数据库显示ID采取,并且我有当重复或类似的文件夹名称返回相同的显示信息的问题。在一个情况我有一个包含三个文件夹的目录,“别名”,“别名1”,“兄弟连”我从我的代码如下输出
*电视节目*
别名....... NO MATCH ...... ADDING ........ DONE
别名1 ...... NO MATCH .... .ADDING .... CANT ADD,ID已存在DB
兄弟...... NO MATCH..ADDING波段的....
之前对context.SaveChanges得到一个UpdateException();行 违反PRIMARY KEY约束'PK_TVShows'。
我可以看到使用SQL事件探查器的问题是,我的应用程序试图执行上的别名显示插入第二次用复制的钥匙,但我不明白为什么。当我在foreach循环的第二个交互(第二个“别名”文件夹)上遍历代码时,绕过了将show实体保存到数据库的代码。
它只是在foreach循环的下一次迭代时,我创建了一个新的“兄弟乐队”TVShow实体吗?我是否实际上到达了将Tvshow添加到上下文并保存的代码,此时应用程序崩溃。在视觉工作室,我可以看到 在崩溃的那一点;
- 在context.TVShows.AddObject(显示) “节目” 实体是 “兄弟连” W /唯一ID
- context.TVShows只包含一个记录,该第一别名实体
但是,SQL事件探查器显示的EntityFramework是不是插入别名第二次,我感到这是为什么
private void ScanForTVShowFolders(GenreDirectoryInfo drive) {
IEnumerable<DirectoryInfo> shows = drive.DirInfo.EnumerateDirectories();
foreach (DirectoryInfo d in shows) {
//showList contains a list of existing TV show names previously queried out of DB
if (showList.Contains(d.Name)) {
System.Console.WriteLine(d.Name + ".....MATCH");
} else {
System.Console.Write(d.Name + "......NO MATCH..ADDING....");
TVShow show = LookUpShowOnline(d.Name, drive.GenreName);
if (show.Id == -1) { // id of -1 means online search failed
System.Console.Write("..........CANT FIND SHOW" + Environment.NewLine);
} else if (context.TVShows.Any(a => a.Id == show.Id)) { //catch duplicate primary key insert
System.Console.Write(".......CANT ADD, ID ALREADY EXISTS IN DB" + Environment.NewLine);
} else {
context.TVShows.AddObject(show);
context.SaveChanges();
System.Console.Write("....DONE" + Environment.NewLine);
}
}
}
private TVShow LookUpShowOnline(string name, string genre) {
string xmlPath = String.Format("http://services.tvrage.com/feeds/search.php?show='{0}'", name);
TVShow aShow = new TVShow();
aShow.Id = -1; // -1 = Can't find
XmlDocument xmlResp = new XmlDocument();
try { xmlResp.Load(xmlPath); } catch (WebException e) { System.Console.WriteLine(e); }
XmlNode root = xmlResp.FirstChild;
if (root.NodeType == XmlNodeType.XmlDeclaration) { root = root.NextSibling; }
XmlNode tvShowXML;
//if (showXML["episode"] == null)
// return false;
tvShowXML = root["show"];
if (tvShowXML != null) {
aShow.Id = System.Convert.ToInt16(tvShowXML["showid"].InnerText);
aShow.Name = tvShowXML["name"].InnerText.Trim();
aShow.StartYear = tvShowXML["started"].InnerText.Trim();
aShow.Status = tvShowXML["status"].InnerText.Trim();
aShow.TVGenre = context.TVGenres.Where(b => b.Name.Trim() == genre).Single();
}
return aShow;
}
}
编辑难倒做更多的阅读我将context.ObjectStateManager添加到我的调试监视列表中,每次我创建一个新的TVShow实体时,都会向_addedEntityStore添加一条新记录。实际上,如果我删除context.TVShows.AddObject(显示)代码仍然更新数据库,所以手动添加到上下文似乎是多余的。