首先:我创建了一个数据优先模型!
我有一个m-to-m的关系。为了处理这种关系,我在:
之间增加了一个实体我想更新所有玩家联赛(添加/删除)。
到目前为止,这是我的代码:
using (BettingLeagueEntities entities = new BettingLeagueEntities())
{
foreach (PlayerCheckBoxList p in this.PlayerList)
{
PlayerLeague pl = new PlayerLeague();
pl.League = this.ActiveLeague;
pl.Player = p.ActivePlayer;
entities.PlayerLeague.Add(pl);
}
entities.SaveChanges();
}
玩家类:
public partial class Player
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Player()
{
this.Bet = new HashSet<Bet>();
this.PlayerLeague = new HashSet<PlayerLeague>();
}
public int PID { get; set; }
public string NickName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string BettingSite { get; set; }
public Nullable<double> Balance { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Bet> Bet { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PlayerLeague> PlayerLeague { get; set; }
}
联赛班级:
public partial class League
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public League()
{
this.Bet = new HashSet<Bet>();
this.PlayerLeague = new HashSet<PlayerLeague>();
}
public int LID { get; set; }
public string Name { get; set; }
public Nullable<System.DateTime> StartDate { get; set; }
public Nullable<System.DateTime> EndDate { get; set; }
public string Path { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Bet> Bet { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PlayerLeague> PlayerLeague { get; set; }
}
PlayerLeague:
public partial class PlayerLeague
{
public int PLID { get; set; }
public int PID { get; set; }
public int LID { get; set; }
public virtual League League { get; set; }
public virtual Player Player { get; set; }
}
它以某种方式工作,但它创建了重复的条目,我不能这样做两次或删除一个条目。
我希望你能帮助我!
编辑:
这不会添加多个条目:
using (BettingLeagueEntities entities = new BettingLeagueEntities())
{
foreach (PlayerCheckBoxList p in this.PlayerList)
{
if(p.IsSelected == true)
{
PlayerLeague pl = new PlayerLeague();
pl.League = this.ActiveLeague;
pl.Player = p.ActivePlayer;
entities.Entry(p.ActivePlayer).State = System.Data.Entity.EntityState.Modified;
entities.Entry(this.ActiveLeague).State = System.Data.Entity.EntityState.Modified;
p.ActivePlayer.PlayerLeague.Add(pl);
this.ActiveLeague.PlayerLeague.Add(pl);
}
}
entities.SaveChanges();
}
p.ActivePlayer.PlayerLeague.Add(pl);
this.ActiveLeague.PlayerLeague.Add(pl);
}
}
但我得到了这个例外:
附加信息:附加类型的实体 'BettingLeague.Model.PlayerLeague'失败,因为另一个实体 相同类型已具有相同的主键值。这可能发生 使用“附加”方法或将实体的状态设置为时 如果图中的任何实体具有“未更改”或“已修改” 冲突的关键值。这可能是因为一些实体是新的和 尚未收到数据库生成的键值。在这种情况下使用 “添加”方法或“已添加”实体状态可跟踪图表和 然后将非新实体的状态设置为“未更改”或“已修改”为 合适的。
答案 0 :(得分:1)
如果将第一个代码块替换为仅分配ID的代码块,是否会产生重复?
using (BettingLeagueEntities entities = new BettingLeagueEntities())
{
foreach (PlayerCheckBoxList p in this.PlayerList)
{
PlayerLeague pl = new PlayerLeague();
pl.LID = ActiveLeague.ID;
pl.PID = p.ActivePlayer.ID;
entities.PlayerLeague.Add(pl);
}
string saveString = ApplicationHelper.Save(entities);
// the saveString would make its way to
// the front-end to be show to the user.
}
更新以显示如何查看导致DbUpdateException的原因。 (应该在您的工具箱中的代码。)
public class ApplicationHelper
{
public static string Save(DbContext db)
{
StringBuilder sb = new StringBuilder();
try
{
sb.Append(db.SaveChanges().ToString() + " changed");
}
catch (DbEntityValidationException ex)
{
foreach (var eve in ex.EntityValidationErrors)
{
sb.AppendFormat(@"Entity of type '{0}' in state '{1}' has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
sb.AppendLine();
foreach (var ve in eve.ValidationErrors)
{
sb.AppendFormat("- Property: '{0}', Error: '{1}'",
ve.PropertyName, ve.ErrorMessage);
}
}
sb.Append("ERROR: " + sb.ToString());
}
catch (DbUpdateException ex)
{
var de = TryDecodeDbUpdateException(ex);
if (de == null)
throw;
foreach (var e in de)
sb.AppendLine(e.MemberNames + " : " + e.ErrorMessage);
sb.Append("ERROR: " + sb.ToString());
}
catch (Exception ex)
{
sb.Append("ERROR: " + (ex.InnerException == null ? ex.Message : ex.InnerException.Message));
}
return sb.ToString();
}
static IEnumerable<ValidationResult> TryDecodeDbUpdateException(DbUpdateException ex)
{
if (!(ex.InnerException is System.Data.Entity.Core.UpdateException) ||
!(ex.InnerException.InnerException is System.Data.SqlClient.SqlException))
return null;
var sqlException =
(System.Data.SqlClient.SqlException)ex.InnerException.InnerException;
var result = new List<ValidationResult>();
for (int i = 0; i < sqlException.Errors.Count; i++)
{
var errorNum = sqlException.Errors[i].Number;
string errorText;
if (_sqlErrorTextDict.TryGetValue(errorNum, out errorText))
result.Add(new ValidationResult(errorText));
}
return result.Any() ? result : null;
}
private static readonly Dictionary<int, string> _sqlErrorTextDict =
new Dictionary<int, string>
{
{547,
"This operation failed because another data entry uses this entry."},
{2601,
"One of the properties is marked as Unique index and there is already an entry with that value."}
};
}