Postgres生成为身份与.NET实体模型冲突

问题描述

我正在使用.NET Core,Postgressqlsqlkata + dapper(NOT EF)构建和使用API​​

我有这2张桌子

CREATE TABLE "UserProfile"(
    "Id" INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,"Deleted" BOOLEAN NOT NULL DEFAULT FALSE,"CreatedBy" VARCHAR(50) NOT NULL,"CreatedTime" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_DATE,"LastModifiedBy" VARCHAR(50),"LastModifiedTime" TIMESTAMP WITH TIME ZONE,"FirstName" VARCHAR(50) NOT NULL,"LastName" VARCHAR(50),"Email" VARCHAR(50) UNIQUE NOT NULL
);
CREATE TABLE "UserLogin"(
    "Id" INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,"Username" VARCHAR(50) UNIQUE NOT NULL,"Password" VARCHAR(200) NOT NULL,"IsLocked" BOOLEAN NOT NULL DEFAULT FALSE,"IsActive" BOOLEAN NOT NULL DEFAULT FALSE,"UserProfileId" INT NOT NULL,CONSTRAINT "FK_UserLogin_UserProfile" FOREIGN KEY("UserProfileId") REFERENCES "UserProfile"("Id")
);

在C#中,我创建了包含表的实体

public class BaseEntity
{
    public int Id { set; get; }
    public bool Deleted { set; get; }
    public string CreatedBy { set; get; }
    public DateTime CreatedTime { set; get; }
    public string LastModifiedBy { set; get; }
    public DateTime? LastModifiedTime { set; get; }

    public BaseEntity()
    {
        this.Deleted = false;
        this.CreatedBy = "SYstem"; //Todo: Change to UserPrincipal
        this.CreatedTime = DateTime.Now;
        this.LastModifiedBy = null;
        this.LastModifiedTime = null;
    }
}

public class UserLogin : BaseEntity 
{
    public string Username { set; get; }
    public string Password { set; get; }
    public bool IsLocked { set; get; }
    public bool IsActive { set; get; }
    public int UserProfileId { set; get; }
}

public class UserProfile:BaseEntity
{
    public string FirstName { set; get; }
    public string LastName { set; get; }
    public string Email { set; get; }

}

如果我想向数据库中插入新记录,那么问题就来了

public async Task<ResponseBase> SignUp(SignUpRequest request)
    {
        ResponseBase result = new ResponseBase();
        try
        {
            using var conn = await db.CreateConnectionAsync();
            var query = new QueryFactory(conn,new PostgresCompiler());
            var scope = conn.BeginTransaction();

            var userProfileId = await query.Query(UserProfileConst.TableName)
                                           .InsertAsync(new UserProfile
                                           {
                                               FirstName = request.FirstName,LastName = request.LastName,Email = request.Email
                                           });

            var affectedUserLogin = await query.Query(UserLoginConst.TableName)
                                               .InsertAsync(new UserLogin
                                               {
                                                   Username = request.Username,Password = Argon2.Hash(request.Password),IsActive = true,IsLocked = false,UserProfileId = userProfileId
                                               });
            
            if (userProfileId > 0 && affectedUserLogin > 0)
            {
                scope.Commit();
                result.Success("Success Insert New User");
            }
            else
            {
                scope.Rollback();
                result.Failed("Success Insert New User");
            }
        }
        catch (Exception e)
        {
            result.Failed(e.Message);
        }
        return result;
    } 

new UserLogin({ })new UserProfile({ })将从IdBaseEntity自动认值设置为0 它将导致Postgres

中的错误
{
    "ackNowledge": 0,"message": "428C9: cannot insert into column \"Id\"","isSuccess": false
}

我知道我可以只创建新的Object而不必定义其类,但是我想知道是否还有其他方法

有人知道吗?

解决方法

您可以在列上使用KeyAttribute批注将其标记为主键,以便在插入/更新查询中将其忽略。

您还可以使用Ignore属性忽略任意字段

public class BaseEntity
{
    [Key]
    public int PrimaryKeyColumnWillBeIgnoredOnInsert { set; get; }
   
    [Ignore]
    public int ThisColumnWillBeIgnoredAlso { set; get; }
}

检查 https://github.com/sqlkata/querybuilder/blob/master/QueryBuilder/ColumnAttribute.cs#L27