微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

EF Code First ApplicationUser 需要 DateTime 未添加

如何解决EF Code First ApplicationUser 需要 DateTime 未添加


我在使用新的 ASP.NET Core 应用程序(代码优先)注册新用户时遇到问题。
注册时,我使用的是从“IdentityUser”继承的“ApplicationUser”。
public class ApplicationUser : IdentityUser
{
    [required]
    [DefaultValue(5)]
    public int ViewerRange { get; set; }
    [DefaultValue(false)]
    [required]
    public bool IsTACAccepted { get; set; }
    public DateTime? TACAccepted { get; set; }
    [required]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime Created { get; set; }
    [required]
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime Modified { get; set; }
    public string Role { get; set; }

    public ApplicationUser()
    {
        Modified = DateTime.Now;
        Created = DateTime.Now;
    }
}

这是 Register.cshtml.cs 的部分

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl ??= Url.Content("~/");
    ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser
        {
            UserName = Input.Email,Email = Input.Email,Role = Input.Role,Created = DateTime.Now,Modified = DateTime.Now,IsTACAccepted = false,ViewerRange = 5
        };


        var result = await _userManager.CreateAsync(user,Input.Password);
        //[...]

注册时,CreateAsync 方法失败并出现以下错误

InvalidOperationException: The value for property 'ApplicationUser.Modified' cannot be set to null because its type is 'System.DateTime' which is not a nullable type.

我不明白为什么会失败。
谁能详细解释一下?
亲切的问候

解决方法

public DateTime? Created { get; set; }
public DateTime? Modified { get; set; }

使用这个,你的模型需要被告知你的数据库中可以有空值,否则它会假设没有。

更新

**I did not actually carefully noticed your error. Now I will update my answer:-**

我看到您没有在控制器中使用此属性。所以最初这个属性可以为空。为此,您发现了这个问题。首先,使用此属性忽略可为空。

试试这个:-

public DateTime TACAccepted { get; set; }  = DateTime.Now;

你可以试试这个,因为你的属性是空的。您可以像上面的代码一样设置此属性以忽略可空值。或者,如果不需要,您可以从模型中删除此属性。我认为它会解决您的问题。

此外,请确保该列在 SQL 数据库中声明为 DateTime。

,

错误的原因是 [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 说它的值是由数据库生成的,所以任何分配的值都应该被忽略。错误表明情况并非如此。

这不是代码中唯一的奇怪之处。 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 在 DateTime 上没有任何意义。 IDENTITY 用于自动递增数字字段。这对于 DateTime 列没有意义。

如果您想自己指定值,请删除 DatabaseGenerated 属性并将它们用作普通字段。您可以通过指定默认属性值来避免显式赋值,例如

public DateTime Created { get; set; } = DateTime.Now;
public DateTime Modified { get; set; } = DateTime.Now;

也可以配置数据库来生成这些值。这在文档中的 Generated Values 文章中进行了描述。 Date/time generation 部分介绍了如何添加 CreatedModified 列。

可以使用 Created 指定 HasDefaultValueSql 列的默认值约束:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Created)
        .HasDefaultValueSql("getdate()");
}

Modified 时间戳需要一个触发器,但不能在 DbContext 的模型中指定。这必须在数据库中创建,或者直接:

CREATE TRIGGER [dbo].[Blogs_UPDATE] ON [dbo].[Blogs]
    AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;

    DECLARE @Id INT

    SELECT @Id = INSERTED.BlogId
    FROM INSERTED

    UPDATE dbo.Blogs
    SET LastUpdated = GETDATE()
    WHERE BlogId = @Id
END

或者通过执行相同脚本的原始 SQL 迁移:

migrationBuilder.Sql(
@"
    EXEC ('CREATE TRIGGER [dbo].[Blogs_UPDATE] ON [dbo].[Blogs]
    AFTER UPDATE
AS
BEGIN
    SET NOCOUNT ON;

    IF ((SELECT TRIGGER_NESTLEVEL()) > 1) RETURN;

    DECLARE @Id INT

    SELECT @Id = INSERTED.BlogId
    FROM INSERTED

    UPDATE dbo.Blogs
    SET LastUpdated = GETDATE()
    WHERE BlogId = @Id
END')");

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。