我正在尝试编写程序来扫描包含tv show文件夹的目录,使用tvrage API查找有关节目的一些详细信息,然后使用实体框架将详细信息保存到数据库中。
我的TVShow表pkey与从tvrage数据库show id获取的值相同,当重复或类似的文件夹名称返回相同的Show info时,我遇到了问题。在我有一个包含三个文件夹的目录的情况下,“Alias”,“Alias 1”,“Band of Brothers”我从我的代码中得到以下输出
* 电视节目 *
Alias .......没有比赛......添加........ DONE
别名1 ......没有匹配.....添加....无法添加,ID已存在于数据库中
兄弟乐队......没有比赛.....ADING ....
在context.SaveChanges()上获取UpdateException之前;线 违反PRIMARY KEY约束'PK_TVShows'。
我可以看到使用SQL分析器,问题是我的应用程序尝试使用重复键第二次在别名显示上执行插入,但我看不出原因。当我在foreach循环的第二次交互(第二个“别名”文件夹)上单步执行代码时,会绕过将show实体保存到数据库的代码。
当我为“兄弟乐队”创建一个新的TVShow实体时,它只在foreach循环的下一次迭代中进行 实际上达到了将Tvshow添加到上下文并保存的代码,此时应用程序崩溃了。在视觉工作室,我可以看到 在崩溃的那一点;
但SQL分析器显示EntityFramework是第二次插入Alias,我很难理解为什么
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(show),代码仍会更新数据库,因此手动添加到上下文似乎是多余的。
答案 0 :(得分:0)
如果您通过foreach循环插入对象&gt;最好将主键保持在外面并使其增加!
例如:int newID = Shows.Select(d =&gt; d.Id).Max();
的foreach(............)
{
show.Id = newID++;
.
.
. //remaining fields
.
context.TVShows.AddObject(显示);
}
context.SaveChanges();
它对我有用...... !!
答案 1 :(得分:0)
结果是context.TVShows.AddObject(show)在我的情况下是不必要的,当这个查询运行时,我无意中将所有创建的show实体添加到上下文
aShow.TVGenre = context.TVGenres.Where(b =&gt; b.Name.Trim()== genre).Single();
这不是我想要的,我只想创建对象,然后决定是否添加它。现在很容易解决,我知道它为什么会发生。