Entity Framework помещает случайный GUID в строку. Пустое поле при сохранении базы данных

Я создал полную привязку EF к одной из наших баз данных (структуру которой я не контролирую) для выполнения некоторых базовых операций CRUD. Пока все идет хорошо. Однако у меня возникла проблема со вставкой одного из моих классов. Он пытается вставить новую запись в таблицу под названием «applmort». Я не буду вдаваться в подробности того, как устроена эта таблица базы данных, поскольку ее создает не моя компания. Но у нас есть к нему доступ и мы можем выполнять с ним операции CRUD.

В этой таблице есть столбец, который я назову UWT, который объявлен как varchar(12). Итак, я настроил конфигурацию EF, чтобы ограничить входящие в нее значения до 12. Вы заметите это в файле конфигурации, который я опубликую. Пока в столбце стоит NOTNULL, я могу просто поставить в столбец пробел varchar и всё в порядке. Никаких ограничений по таблице для этого нет.

Итак, когда я пытаюсь добавить новую запись, я не указываю это поле в объекте. Я могу сделать это с кучей других столбцов в таблице, и поскольку мой файл конфигурации указывает EF вставить строку. По умолчанию это пустая строка, все работает удобно. За исключением этой UWT рубрики. Он отказывается и сообщает мне, что произошла ошибка усечения. Поскольку я ввожу пустую строку, это кажется странным. Я копаю и понимаю, что EF пытается создать этот столбец UWT в качестве альтернативного ключа, а затем заполняет его случайным GUID, который я никогда не говорил ему использовать. Я отслеживаю это и обнаруживаю, что у меня есть еще одна таблица, подключенная к этой через файл конфигурации (это должен быть второй класс конфигурации, который я перечислил ниже). Этот другой объект связан с моим объектом Application через UWT. Это должно быть нормально, и я не думал, что установка этого вызовет проблемы. Однако это так. Когда я удаляю «один ко многим» из второго объекта, чтобы разорвать ссылку, запись вставляется правильно.

Еще один обходной путь, который я нашел, заключался в том, чтобы указать столбец UWT в объекте Application как пустую строку до того, как он достигнет значения по умолчанию в конфигурации. Это также позволяет без проблем вставить запись.

Я мог бы использовать любой из этих обходных путей. Второй будет работать лучше всего и позволит мне сохранить ссылку на таблицу. Но это кажется очень и очень странным. Этого не происходит ни с одной другой ссылкой на таблицу, которую я создаю, поэтому я должен спросить: я делаю здесь что-то не так? Я где-то установил что-то, из-за чего GUID помещается в явно не-GUID столбец? Я не могу, хоть убей, найти это.

public class Application
{
    public DateTime? ChangeDate { get; set; }
    public int ID { get; set; }
    public DateTime? ApplicationDate { get; set; }
    public string StructureID { get; set; } = null!;
    public string UWT { get; set; } = null!;
    public int UnitNumber { get; set; }
    
    public virtual Structure Structure { get; set; } = null!;
    public virtual ICollection<ApplicationHold> ApplicationHolds { get; set; } = [];
}

public class ApplicationHold
{
    public DateTime? ChangeDate { get; set; }
    public string UWT { get; set; } = null!;
    public int ID { get; set; }

    public virtual Application Application { get; set; } = null!;
}

public class ApplicationConfig : IEntityTypeConfiguration<Application>
{
    public void Configure(EntityTypeBuilder<Application> entity)
    {
        entity.ToTable("applmort");

        entity.HasKey(e => e.ID);

        entity.Property(e => e.ChangeDate)
            .HasColumnName("changedate")
            .HasColumnType("datetime")
            .HasDefaultValue(DateTime.Now)
            .IsRequired();
        entity.Property(e => e.ID)
            .HasColumnName("id")
            .UseIdentityColumn();
        entity.Property(e => e.ApplicationDate)
            .HasColumnName("appldate")
            .HasColumnType("datetime")
            .HasDefaultValue(DateTime.Now);
        entity.Property(e => e.StructureID)
            .HasColumnName("stru")
            .HasMaxLength(3)
            .HasDefaultValue(string.Empty)
            .IsRequired();
        entity.Property(e => e.UWT)
            .HasColumnName("uwt")
            .HasColumnType("varchar")
            .HasMaxLength(12)
            .HasDefaultValue(string.Empty)
            .IsRequired();
        entity.Property(e => e.UnitNumber)
            .HasColumnName("units")
            .HasColumnType("int")
            .HasDefaultValue(0)
            .IsRequired();

        entity.HasOne(e => e.Structure).WithMany(e => e.Applications)
            .HasForeignKey(e => e.LoanStructureID)
            .HasPrincipalKey(e => e.LoanStructureID)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);
    }
}

public class ApplicationHoldConfig : IEntityTypeConfiguration<ApplicationHold>
{
    public void Configure(EntityTypeBuilder<ApplicationHold> entity)
    {
        entity.ToTable("applhold");

        entity.HasKey(e => e.ID);

        entity.Property(e => e.ChangeDate)
            .HasColumnName("changedate")
            .HasColumnType("datetime")
            .HasDefaultValue(DateTime.Now)
            .IsRequired();
        entity.Property(e => e.ID)
            .HasColumnName("id")
            .UseIdentityColumn();
        entity.Property(e => e.UWT)
            .HasColumnName("uwt")
            .HasColumnType("varchar")
            .HasMaxLength(12)
            .HasDefaultValue(string.Empty)
            .IsRequired();

        entity.HasOne(entity => entity.Application).WithMany(e => e.ApplicationHolds)
            .HasForeignKey(entity => entity.UWT)
            .HasPrincipalKey(e => e.UWT)
            .IsRequired(false)
            .OnDelete(DeleteBehavior.NoAction);
    }
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

EF пытается создать уникальное ограничение для поля UWT, возможно, тем, как он понимает связь между Application и ApplicationHold.

Вы можете попробовать не использовать HasDefaultValue(string. Empty), так как кажется, что даже наличия этого кода достаточно, чтобы EF автоматически генерировал отношения, стирал конфигурации значений по умолчанию и обрабатывал их в своем приложении.

entity.Property(e => e.UWT)
            .HasColumnName("uwt")
            .HasColumnType("varchar")
            .HasMaxLength(12)
            .HasDefaultValue(string.Empty) 
            .IsRequired();

Установка этого значения напрямую должна решить проблему при вставке записи.

Application application = new()
{
    UWT = string.Empty, 
};

Да, кажется, это хорошее решение. Однако это все еще странно, поскольку у меня есть куча других ссылок на таблицы и строки. Пустой набор для множества других мест... почему именно это, остается загадкой. Но спасибо! Это хороший способ справиться с этим. Если кто-нибудь еще знает, ПОЧЕМУ это происходит... Я хотел бы знать.

CrystalBlue 28.08.2024 20:35

Другие вопросы по теме