EF DbSet.Find()返回Detached Entity

时间:2015-04-17 14:50:03

标签: c# entity-framework sql-server-ce sql-server-ce-4

我有一个非常简单的Entity只有4个字段:名称,州,城市和ID以及一些验证。

[Table("Places")]
public class Place : BindableBase, IDataErrorInfo
{
    private string name;
    private string city;
    private Estado state;
    private int id;

    [Required]
    [StringLength(500)]        
    public string Name
    {
        get { return this.name; }
        set { SetProperty(ref name, value); }
    }

    [Required]
    [StringLength(500)]
    public string City
    {
        get { return this.city; }
        set { SetProperty(ref city, value); }
    }

    [Required]        
    public State State
    {
        get { return this.state; }
        set { SetProperty(ref state, value); }
    }

    [Key]
    public int Id
    {
        get { return this.id; }
        set { SetProperty(ref id, value); }
    }

    [NotMapped]
    public bool IsValid
    {
        get 
        {
            return Validator.TryValidateObject(this, new ValidationContext(this), new Collection<ValidationResult>(), true);
        }
    }

    #region IDataErrorInfo Members
    /// <summary>
    /// IDataErrorInfo Interface Error Message for the object.
    /// </summary>
    [NotMapped]
    public string Error
    {
        get { throw new NotImplementedException(); }
    }

    public string this[string propertyName]
    {
        get 
        {
            var context = new ValidationContext(this)
            {
                MemberName = propertyName
            };

            var results = new Collection<ValidationResult>();
            bool isValid = Validator.TryValidateObject(this, context, results, true);

            if (!isValid)
            {
                ValidationResult result = results.SingleOrDefault(p =>
                                                                  p.MemberNames.Any(memberName =>
                                                                                    memberName == propertyName));

                return result == null ? null : result.ErrorMessage;
            }

            return null; 
        }
    }
    #endregion
}

我可以将它添加到数据库中,但是一旦我尝试更新它,我就会得到一个例外。

我正在使用:

public void UpdatePlace(Place place)
{
    var entity = context.Places.Find(place.Id);

    if (entity == null)
    {
        throw new InvalidOperationException("Place not found.");
    }

    context.Entry(place).CurrentValues.SetValues(place);
    context.SaveChanges();
}

当我到达

context.Entry(place).CurrentValues.SetValues(place);

我得到一个例外:

  

System.InvalidOperationException

     

无法为类型实体调用“成员'CurrentValues'   '放置'因为实体在上下文中不存在。   要向上下文添加实体,请调用Add或Attach方法   DbSet“。

context.Entry告诉我确实实体是分离的

context.Entry shows detached

DbSet.Find()方法的文档清楚地表明Find()应返回附加实体,以防在数据库中找到一个实体:

  

查找具有给定主键值的实体。如果上下文中存在具有给定主键值的实体,则会立即返回该实体而不向商店发出请求。否则,向具有给定主键值的实体的商店发出请求,如果找到该实体,则将其附加到上下文并返回。如果在上下文或商店中找不到实体,则返回null。

因此,当我尝试获取CurrentValues时,由于实体已分离,它会抛出Exception ...但据我所知,应该有一个附加实体,或者为null,没别的......

我在网上找不到任何关于此错误的信息,我使用SQL CE 4.0作为数据库,有谁知道发生了什么?

我认为每次从Attach获取实体时我都可以Find实体,但我仍然想了解我的软件发生了什么,因为这不应该发生。

1 个答案:

答案 0 :(得分:2)

我认为您应该将此行更改为:

  context.Entry(entity).CurrentValues.SetValues(place);