如何在发出 post 请求时避免重复条目?

How to avoid duplicate entries when making a post request?

我在 ASP.NET 中发布带有嵌套对象的对象时遇到问题。我有一个状态 class,它有一个用户对象(发布状态的用户)。当以 JSON 形式发布状态时,它也有用户对象。问题是,它没有添加该用户的状态,而是添加了状态和一个新用户,这显然不是我想要的。

这是 JSON 的样子。 id为2的用户已经存在于数据库中,但是在发布时,创建了另一个用户。

{
    "User": {
        "Id": 2,
        "First": "Tobin",
        "Last": "Brown",
        "Email": null,
        "Profile": null,
        "Height": 75,
        "Weight": 165,
        "BirthDate": "1991-04-24T00:00:00"
    },
    "Id": 2,
    "Type": 0,
    "Time": "2015-03-08T11:01:48"
}

用户class:

public class User
{
    [Key]
    public int Id { get; set; }
    public string First { get; set; }
    public string Last { get; set; }
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }
    public Profile Profile { get; set; }
    public double Height { get; set; }
    public double Weight { get; set; }
    public DateTime BirthDate { get; set; }
    public virtual List<TeamUser> Teams { get; set; }
    [JsonIgnore]
    public virtual List<Status> Statuses { get; set; }
}

状态class:

public class Status
{
    [Key]
    public int Id { get; set; }
    public StatusType Type { get; set; }
    public DateTime Time { get; set; }
    public virtual User User { get; set; }
    public virtual Activity Activity { get; set; }
}

最后是我的控制器方法,它使用 entity framework:

处理将状态添加到数据库
[ResponseType(typeof(Status))]
public IHttpActionResult PostStatus(Status status)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }
    db.Statuses.Add(Status);
    db.SaveChanges();
    return Ok(status);
}

如果我在 JSON 中将用户 ID 传递给它,为什么它会创建一个新用户?

我认为您需要在调用 db.SaveChanges() 之前将 EntityState 设置为 Unchanged

如下所示:

db.Entry<User>(status.User).State = EntityState.Unchanged; 

有关详细信息,请访问此 MSDN article

由于状态条目是新的,entity framework 将其所有关联对象视为新的。您上面的示例可以修改如下

1) 将用户 ID 属性 添加到状态 class 2) 将UserId 属性设置为JSON中对应的用户对象的ID。现在看起来像这样

{
    "Id": 2,
    "Type": 0,
    "UserId": 2,
    "Time": "2015-03-08T11:01:48"
}

3) 在您的控制器中,设置 status.User = null

您数据库中的 Status table 应该将 UserId 外键映射到用户的 ID 列。

您可能需要将现有用户重新附加到数据库上下文(如果设置 status.User=null 不起作用)

if (status.User!=null)
{
    db.Users.Attach(status.User)
    db.Entry<User>(status.User).State = EntityState.Unchanged;
}