GOOGLE ADS

четверг, 28 апреля 2022 г.

Entity Framework: невозможно добавить запись

Я новичок в разработке на С# и пытаюсь написать что-то, что может вставлять запись в БД. У меня есть простой тест, который, как я надеялся, вставит запись в базу данных при его запуске.

Модель:

namespace Users.Models;
using System.ComponentModel.DataAnnotations.Schema;
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
public string HashedPassword { get; set; }
public DateTime Created { get; set; }
}

Контрольная работа:

namespace Database.Tests;
using Users.Models;
using Xunit;
public class ReferrerTests
{
[Fact]
public void TestInsert()
{
User user = new()
{
Name = "Bob",
EmailAddress = "bob@email.com",
HashedPassword = "hgfj",
};
using MyDbContext ctx = new();
ctx.Users.Add(user);
}
}

Контекст базы данных:

namespace Database;
using Users.Models;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using Npgsql;
[DbConfigurationType(typeof(Config))]
[SuppressDbSetInitialization]
public class MyDbContext: DbContext
{
public MyDbContext(): base(MakeConnString()) {}
private static string MakeConnString()
{
// Will be moving these to a common location
string OptEnv(string key, string default_) =>
Environment.GetEnvironmentVariable(key)?? default_;
string Env(string key) =>
Environment.GetEnvironmentVariable(key)?? throw new MissingFieldException(key);
NpgsqlConnectionStringBuilder builder = new()
{
Host = Env("PGHOST"),
Port = int.Parse(OptEnv("PGPORT", "5432")),
SslMode = Enum.Parse<SslMode>(OptEnv("PGSSLMODE", "Require")),
TrustServerCertificate = true,
Database = OptEnv("PGDATABASE", "postgres"),
Username = OptEnv("PGUSER", "postgres"),
Password = Env("PGPASSWORD")
};
return builder.ConnectionString;
}
public DbSet<User> Users { get; set; }
}

При запуске этого кода я получаю:

System.NullReferenceException: ссылка на объект не указывает на экземпляр объекта.

Я думаю, что у меня должно быть что-то, что мешает сопоставлению с моей базой данных, но я не смог понять это.

РЕДАКТИРОВАТЬ

Я думаю, что, вероятно, важно, чтобы я также показывал DDL таблицы:


create table public.user
(
id integer generated always as identity primary key,
name text not null
constraint user_name_check
check (length(name) > 0),
email_address text not null unique
constraint user_email_address_check
check (email_address ~* '^.+@.+\..+$'),
-- Ideally use something like
-- https://www.postgresql.org/docs/13/pgcrypto.html
hash_password text not null
constraint user_password_hash_check
check (length(password_hash) > 0),
created timestamp with time zone default CURRENT_TIMESTAMP not null
constraint user_created_check
check (created <= CURRENT_TIMESTAMP)
);
alter table public."user"
owner to postgres;

РЕДАКТИРОВАТЬ 2:

Предложения использовать аннотации, чтобы попытаться напрямую сопоставить модель с DDL — все равно выдает ту же ошибку, но это наша новая модель.

namespace Users.Models;
using System.ComponentModel.DataAnnotations.Schema;
[Table("user", Schema="public")]
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("id")]
public int Id { get; set; }

[Column("name")]
public string Name { get; set; }

[Column("email_address")]
public string EmailAddress { get; set; }

[Column("hash_password")]
public string HashedPassword { get; set; }

[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[Column("created")]
public DateTime Created { get; set; }
}


Решение проблемы

Я не знаю о вашей БД, но ваша модель требует, чтобы столбец Id имел значение (он не может быть нулевым). Поэтому вам нужно указать значение, чтобы сделать это.

Если ваш тип столбца Id — Serial на стороне БД, просто украсьте свой столбец Id:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...