我不知道我是否遗漏了某些东西......无论如何:
例如,您可以看到具有“HomeTeam”=“Forest Green Rovers”属性的对象具有state ='Unchanged'。无论如何,在我的情况下,所有实体都“保持不变”。所以,如果我是正确的,saveChanges不应该尝试在我的表中插入那些,但这就是它发生的事情:
主键已被违反,但EF不应该尝试添加此记录(属性为HomeTeam ='Forest Green Rovers'),因为它是'未更改',对吧?
为什么EF这样做?
实体:
{
using System;
using System.Collections.Generic;
public partial class MatchInfo
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public MatchInfo()
{
this.Sport = "Soccer";
this.OddsInfoes1X2 = new HashSet<OddsInfo1X2>();
this.Odds1X2Movements = new HashSet<OddsMovement>();
this.OddsInfoOverUnders = new HashSet<OddsInfoOverUnder>();
this.OddsMovementOverUnders = new HashSet<OddsMovementOverUnder>();
this.HistoryResults = new HashSet<HistoryResult>();
}
public string League { get; set; }
public System.DateTime Date { get; set; }
public string HomeTeam { get; set; }
public string AwayTeam { get; set; }
public string FinalScore { get; set; }
public string Sport { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OddsInfo1X2> OddsInfoes1X2 { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OddsMovement> Odds1X2Movements { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OddsInfoOverUnder> OddsInfoOverUnders { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OddsMovementOverUnder> OddsMovementOverUnders { get; set; }
public virtual TeamsStatFinal TeamsStatFinal { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<HistoryResult> HistoryResults { get; set; }
}
}
更多信息:
foreach (something){
/*iterating on a web page and where I build the object oMatchInfo */
if (oMatchInfo != null)
{
oMatchInfoTemp = (from m in context.MatchInfoes where m.HomeTeam == oMatchInfo.HomeTeam && m.AwayTeam == oMatchInfo.AwayTeam && m.Date == oMatchInfo.Date select m).FirstOrDefault<MatchInfo>();
if (oMatchInfoTemp == null)
{
context.MatchInfoes.Add(oMatchInfo);
}
else
{
context.OddsInfoes1X2.AddRange(oMatchInfo.OddsInfoes1X2);
}
}
}
/* here there is the context.saveChanges() - the context is the same */
OPS。我发现了我的错误,它真的很愚蠢:-(在一个相关的函数里面有一些未注释的代码,我在那里添加实体而不检查PK约束。 国家'Unchanged'(第一张图片)让我困惑,我一直专注于那...... 对不起: - )
答案 0 :(得分:3)
如果要将实体添加到而非新实体(PK已存在于数据库中)的上下文中,则需要附加实体而不是添加实体。
此处有更多详情https://msdn.microsoft.com/en-us/library/jj592676(v=vs.113).aspx
详细说明,仔细查看上下文内容。您将找到具有已添加状态的实体。
答案 1 :(得分:3)
您正在向数据库添加现有条目。
if (oMatchInfo != null)
{
oMatchInfoTemp = (from m in context.MatchInfoes where m.HomeTeam ==
oMatchInfo.HomeTeam && m.AwayTeam == oMatchInfo.AwayTeam && m.Date ==
oMatchInfo.Date select m).FirstOrDefault<MatchInfo>();
if (oMatchInfoTemp == null)
{
context.MatchInfoes.Add(oMatchInfo);
}
else
{
context.OddsInfoes1X2.AddRange(oMatchInfo.OddsInfoes1X2);
}
}
这样您就可以添加一个ID与数据库中的条目匹配的模型,因此您的数据库会出现cannot insert duplicate key
错误。
答案 2 :(得分:2)
我认为问题在于:
if (oMatchInfo != null)
{
oMatchInfoTemp = (from m in context.MatchInfoes where m.HomeTeam == oMatchInfo.HomeTeam && m.AwayTeam == oMatchInfo.AwayTeam && m.Date == oMatchInfo.Date select m).FirstOrDefault<MatchInfo>();
if (oMatchInfoTemp == null)
{
context.MatchInfoes.Add(oMatchInfo);
}
else
{
// CODE SMELL
context.OddsInfoes1X2.AddRange(oMatchInfo.OddsInfoes1X2);
}
}
在其他情况下,您正在重新添加许多已插入数据库的实体,这就是重新链接您当前匹配的内容。
也许你想在现有的X2和新的X2之间插入差异。典型代码如下:
context.OddsInfoes1X2.AddRange(oMatchInfo.OddsInfoes1X2.Where(t => !oMatchInfoTemp.OddsInfoes1X2.Contains(t)))
你在else语句中想做什么?
希望这有帮助!
答案 3 :(得分:1)
仍然无法从您的代码中看出,因为您的表现不够。
您需要为我们提供更多代码,以便了解您调用自己的原因。
我希望这段代码可以帮助您理解,这不是一个适合您的解决方案,我只是想表明您的for-each看起来不正确,取决于您在做什么时,但是因为您不是显示我们无法告诉的所有代码。
public void Save(TEntity entity) //change this to your entity
{
if(entity == null)
return;
//change this to your key, this is the identifier for new
if (entity.Id == 0)
{
entity.CreateOnDateTime = DateTime.Now;
Context.Set<TEntity>().Add(entity);
}
Context.SaveChanges(); //this may not suit your design
}