Тип данных TinyInt в SQL Server не сохраняет целое число 0 при использовании LINQ (C#)

#c# #.net #sql-server #entity-framework #linq

Вопрос:

У меня есть такая простая сущность, как эта:

 public partial class TestEntity
{   public int Id { get; set; } // primary key
    public string Relation { get; set; }
    public byte? Age { get; set; }
    public byte Alive { get; set; }
}
 

Когда я вызываю DB.add(SampleEntity) add DB.SaveChanges() , то происходит следующее в свойстве alive, я передаю 0, оно меняется на 1 при сохранении теперь тип данных в БД — крошечный int, который по какой-то причине должен разрешать 0-255, он не принимает 0.

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

1. Проблема будет в другом. Либо инструмент, который вы используете для просмотра элементов базы данных, не синхронизирован, либо что-то изменяет вашу сущность

Ответ №1:

Короткий ответ

Вы забыли дать TestEntity первичный ключ.

Объяснение

TestEntity у него нет первичного ключа. Из-за его отсутствия Entity Framework предполагает, что свойство Alive должно содержать первичный ключ. При сохранении он автоматически сгенерирует значение для первичного ключа.

Вы можете проверить это, добавив второй тест. Что происходит с ценностью Жизни?

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

Поэтому, если у вас есть база данных с Продуктами, Клиентами, Заказами и т. Д., У вас будут классы «Продукт», «Клиент», «Заказ» и таблицы «Продукты, клиенты, заказы». У каждого Клиента ноль или более Заказов, поэтому у Клиента есть заказы на недвижимость (множественное число). Каждый Заказ является Заказом ровно одного Клиента, поэтому Заказ имеет свойство Клиента (единственное число).

Следуя соглашениям, вам не нужно много рассказывать entity framework. Однако, если у вас уже есть существующая база данных, а ваши таблицы и столбцы в таблицах имеют другие имена, чем предполагают соглашения, вам необходимо сообщить entity framework.

Еще один совет: ваша тестируемость представляет собой строку в вашей таблице тестируемости. Невиртуальные свойства TestEntity представляют столбцы таблицы. Виртуальные свойства представляют отношения между таблицами (один ко многим, многие ко многим, …)

Поэтому сделайте TestEntity простым и понятным POCO: классом, в котором есть только get/set. Не добавляйте методы или свойства, которые делают больше, чем просто получение/установка

Вернемся к вашему вопросу

 public class Test
{
    public int Id {get; set;}            // Primary key

    public string Relation { get; set; }
    public byte? Age { get; set; }
    public byte Alive { get; set; }
 

Кстати, вы уверены, что Alive-это не логическое значение? Я могу представить, что вы Живы или не живы, но что значит Жив = 4? Подумайте об использовании идентификаторов, которые правильно описывают, что это значит. Будущие читатели будут хвалить вас за это.

Виртуальные свойства указывают на связи с другими таблицами. Например, если каждый тест имеет ноль или более результатов тестирования (отношение «один ко многим»), добавьте следующее свойство:

     public virtual ICollection<TestResult> TestResults {get; set;}
 

Это ан ICollection<TestResult> , а не а List<TestResult> . В конце концов, что бы TestResults[4] это значило? Коллекция ICollection интерфейса содержит достаточно свойств для добавления / удаления / изменения результатов теста этого теста.

Если этот Тест является Тестом Студента, то существует отношение «один ко многим» со Студентами: у каждого Студента ноль или более Тестов, каждый Тест-это Тест ровно одного Студента, а именно Студента, на которого ссылается внешний ключ.

Добавьте следующие свойства:

 public int StudentId {get; set;}      // a real column in the table: non-virtual
public Student Student {get; set;}    // represents a relation: virtual
 

Конечно, в классе ученика вам нужно добавить:

 public virtual ICollection<Test> Tests {get; set;}



class MyDbContext : DbContext
{
    public DbSet<Test> Tests {get; set;}
    public DbSet<TestResult> TestResults {get; set;}
    public DbSet<Student> Students {get; set;}
}
 

Поскольку я следовал соглашениям, entity framework сможет обнаруживать таблицы, столбцы в таблицах, функции столбцов (первичный / внешний ключ) и отношения между таблицами. Вам понадобятся атрибуты или fluent API только в том случае, если вы решите отклониться от соглашений. Но это вне вашего вопроса.

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

1. на самом деле у него есть первичный ключ