我試圖寫一個程序來掃描包含電視節目的文件夾目錄,查找有關使用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(顯示)代碼仍然更新數據庫,所以手動添加到上下文似乎是多餘的。