如何在 Entity Framework 中保存对象,同时为其列之一使用数据库生成的选项?

How to save an object in Entity Framework while using a database generated option for one of its columns?

我的项目中有一个网页,用户在其中注册了他们的信息,该信息通过前端的 api 调用发送到我的控制器。在我的控制器中,我试图用数据创建一个对象,但创建该对象的唯一方法是在我的参数中使用硬编码 ID。我需要自动创建 ID,而无需明显地对其进行硬编码。

控制器

// POST api/values
[HttpPost]
public void Post(string username, string password, string email, string role)
{
    int id = 1;
    Users user = new Users(id, username, password, email, role);
    _repository.CreateUser(user);
    _repository.SaveChanges();
}

型号

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace IssueTracker.Models
{
    public class Users
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int id { get; set; }

        [Required]
        public string username { get; set; }

        [Required]
        public string password { get; set; }

        [Required]
        public string email { get; set; }

        [Required]
        public string role { get; set; }

        public Users(int id, string username, string password, string email, string role)
        {
            this.id = id;
            this.username = username;
            this.password = password;
            this.email = email;
            this.role = role;
        }

        public Users()
        {

        }

    }
}

界面

using IssueTracker.Models;

namespace IssueTracker.Data
{
    public interface IIssueTrackerRepo
    {
        bool SaveChanges();
        //IEnumerable<Command> GetAllCommands();
        //Command GetCommandById(int id);
        void CreateUser(Users cmd);
        //void UpdateCommand(Command cmd);
        //void DeleteCommand(Command cmd);
    }
}

接口实现

using System;
using IssueTracker.Models;
namespace IssueTracker.Data
{
    public class SqlUsersRepo: IIssueTrackerRepo
    {
        private readonly UsersContext _context;

        public SqlUsersRepo(UsersContext context)
        {
            _context = context;
        }

        public void CreateUser(Users user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }
            
            _context.Users.Add(user);
        }

        public bool SaveChanges()
        {
            return (_context.SaveChanges() >= 0);
        }
    }
}

signup.js

import React, { Component } from "react";
import { useState, useEffect } from "react";
import { Grid, TextField, Button, Typography } from "@material-ui/core";

const Signup = () => {
    const [username, setUsername] = useState();
    const [password, setPassword] = useState();
    const [email, setEmail] = useState();
    const [role, setRole] = useState()

    const post = () => {
        const requestOptions = {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
                username: username,
                password: password,
                email: email,
                role: role
            }),
        };
        fetch("https://localhost:5001/api/IssueTracker", requestOptions)
            .then((response) => response.text())
            .then((data) => {

            })
    }

    return (
        <div>
            <body>
                <form action="#" method="POST">
                    <TextField onChange={(e) => setUsername(e.target.value)}> </TextField>
                    <br>
                    </br>
                    <TextField onChange={(e) => setPassword(e.target.value)}> </TextField>
                    <br>
                    </br>
                    <TextField onChange={(e) => setEmail(e.target.value)}> </TextField>
                    <br>
                    </br>
                    <TextField onChange={(e) => setRole(e.target.value)}> </TextField>
                    <br>
                    </br>
                    <Button onClick={() => post()}> Sign Up</Button>
                </form>
            </body>
        </div>
    );
}



export default Signup;

从构造函数中删除 id 参数 -

public Users(string username, string password, string email, string role)
{
    this.username = username;
    this.password = password;
    this.email = email;
    this.role = role;
}

注解-

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

将在数据库端为您处理 Id 的创建。只需创建没有 Id 的实体并保存它 -

[HttpPost]
public void Post(string username, string password, string email, string role)
{
    Users user = new Users(id, username, password, email, role);
    _repository.CreateUser(user);
    _repository.SaveChanges();
}

编辑:
要解决您在评论中提到的更多问题,请执行以下操作 -

  • 在客户端不要JSON.stringify正文-
const requestOptions = {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: {
        username: username,
        password: password,
        email: email,
        role: role
    }
};
  • 在 Api 末将您的 Post 方法更改为 -
[HttpPost]
public void Post([FromBody]User user)
{
    _repository.CreateUser(user);
    _repository.SaveChanges();
}

内置 ModelBinding 功能将根据您在请求正文中传递的 json 对象在后台为您创建用户实体。

注意:要使其生效,json 对象的 属性 名称应与 User 实体的 属性 名称匹配。