2010-11-17 87 views
2

我正在为一个小型项目使用实体框架v4。通常我使用NHibernate。我的问题是我无意中添加了一个代码,该代码添加了一个已经保存到数据库上下文集合的对象,并且当我执行SaveChanges()时,EF制作了该对象的副本,并为其提供了一个新的主键。实体框架添加现有项目导致克隆

虽然这很有用,但它不是我想要的。有没有办法关闭该功能,而是抛出异常?

UPDATE:CODE现在包括

public class CcUser 
{ 
    public int Id { get; set; } 
    [StringLength(50)] 
    public string TrackingId { get; set; } 
    [StringLength(50)] 
    public string MembershipGuid { get; set; } 

    public bool CookiesConfirmed { get; set; } 
    [StringLength(200)] 
    public string Email { get; set; } 

    public DateTime Modified { get; set; } 

} 

public class MyDbContext : DbContext 
{ 
    public DbSet<CcUser> Users { get; set; } 

} 

MyDbContext db = new MyDbContext(); 

var ccUser = db.Users.FirstOrDefault(u => u.TrackingId == id); 
ccUser.Modified = DateTime.UtcNow; 
db.Users.Add(ccUser); 
db.SaveChanges(); 
+0

你可以显示代码引起的问题? – 2010-11-18 00:16:04

+0

添加代码,谢谢。 – 2010-11-18 17:09:13

回答

1

你怎么知道这是同一个对象?

例如,如果是因为它具有相同的名称,那么您可以在名称字段中添加唯一索引。这样添加一个重复的行会引发异常。

+0

它有相同的主键。我用FirstOrDefault检索它,修改了一个非关键属性,并添加到列表中,并保存。结果是另一个对象,而不是一个例外。 – 2010-11-18 01:17:37

1

你是否尝试过没有添加ccuser的行(例如倒数第二行)。如果对象已经连接到上下文,则savechanges()应该保持更改。如果这不起作用,请尝试在savechanges()之前调用detectchanges()。

+0

我知道,但是如果我不小心添加了一个现有对象,我想EF会抛出一个PK冲突异常,而不会覆盖我的PK和克隆! – 2010-11-18 19:41:30

+1

是您的主要标识列吗?如果是这样,那么我认为ef code-first会将其标记为存储区生成,并且任何添加实体的尝试都将忽略之前设置的任何值。我认为你要么必须首先检查一个实体是否与该主键一起存在,并更新相关的实体或尝试将一个分离的实体附加到上下文中。添加做它的名字暗示 – 2010-11-18 22:09:18

0

大家谁遇到这个问题:

方法.Add标记entityEntityState.Added。并且,当您在上下文项EF中添加存在时,会因为延迟加载而将其视为新对象。

然后context.SaveChanges()将为添加的项目生成新的主键并将其保存到DB。如果您不需要该功能,请使用AddOrUpdate

这里相关的问题MSDN