EntityFramework代码第一个中的DateTime列未按预期工作

本文关键字:工作 DateTime 代码 第一个 EntityFramework | 更新日期: 2023-09-27 18:21:35

我有基本型号User和两个附加型号UserCreateModelUserEditModelUserCreateModel工作得很好,创建了用户,但当我尝试编辑用户时,它会给我错误。

我不明白他为什么在datetime上操作,因为数据库中已经有了有效的datetime属性。我只想更新Name属性。我在这里做错了什么?

错误

将datetime2数据类型转换为datetime数据类型导致值超出范围。语句已终止。

控制器

public HttpResponseMessage PutUser(int id, UserEditModel user)
{
    if (!ModelState.IsValid)
    {
        return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
    }
    if (id != user.Id)
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }
    db.Entry(user).State = EntityState.Modified;
    try
    {
        db.SaveChanges(); // Exception here, all validation passed with success
    }
    catch (DbUpdateConcurrencyException ex)
    {
        return Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
    }
    return Request.CreateResponse(HttpStatusCode.OK);
}

型号

public class User
{
    public int Id { get; set; }
    public virtual DateTime CreatedDateTime { get; set; }
    public virtual string Username { get; set; }
    public virtual string Password { get; set; }
    public virtual string PasswordSalt { get; set; }
    public virtual string AccessToken { get; set; }
    public virtual string Name { get; set; }
}
public class UserEditModel : User
{
    [Required]
    public override string Name { get; set; }
}

EntityFramework代码第一个中的DateTime列未按预期工作

当您将实体映射到数据库时,您需要告诉实体框架使用正确的列类型。

如果你正在使用流利的API,你可以这样做:

Property(p => p.CreatedDateTime).HasColumnType("datetime2");

或者如果您喜欢直接在POCO:上使用列属性

public class User
{   
    public int Id { get; set; }
    [Column(TypeName = "DateTime2")]
    public virtual DateTime CreatedDateTime { get; set; }
    public virtual string Username { get; set; }
    public virtual string Password { get; set; }
    public virtual string PasswordSalt { get; set; }
    public virtual string AccessToken { get; set; }
    public virtual string Name { get; set; }
}

小心;根据您配置实体框架的方式,您现有的数据库可能会被删除并重新创建以说明更改

有关更多信息,请参阅以下博客文章:

  • 使用Fluent API配置/映射属性和类型
  • 使用数据注释配置/映射特性和类型

通过设置db.Entry(user).State = EntityState.Modified;,您告诉EF您想要更新user的所有属性。并且由于您的UserEditModel派生自User实体,EF将尝试更新所有实体属性。

我不知道为什么从实体派生编辑模型,但它会在您的场景中引发问题。我更喜欢从Db加载用户,更新你想要的属性并保存它:

var dbUser = db.Users.Find(user.Id);
dbUser.Username = user.Name;
db.SaveChanges();

一般来说,你可以更新多个属性,比如:

var dbUser = db.Users.Find(user.Id);
db.Entry(dbUser).CurrentValues.SetValues(user);
db.SaveChanges();

但它要求编辑模型中的特性与实体特性具有相同的名称(并且编辑模型不是从实体派生的)。