Сопоставление длинного свойства данных с int в базе данных

Во всех примерах, которые я видел, в качестве идентификаторов используются int32s. Это не всегда практично в производственной среде. Некоторые из наших баз данных имеют идентификаторы идентификаторов, которые находятся в области int64s, поэтому наша практика всегда использовать long для свойств наших идентификаторов. Однако SQL Server имеет более высокие максимальные значения для типа столбца int.

Я делаю первое доказательство концепции с помощью Entity Framework версии 6. С long ID невозможно сопоставить объект с базой данных.

Я использую Fluent API для всех своих карт. Прямо сейчас это выглядит для идентификатора:

Property(s => s.ID).HasColumnName("spcID");

Если я добавлю .HasColumnType("int") в конец вышеупомянутого, это даст мне следующую ошибку:

Указанная схема недействительна. Ошибки: (7,12): ошибка 2019: указанное сопоставление элементов недопустимо. Тип «Edm.Int64 [Nullable = False, DefaultValue =]» члена «ID» в типе «EFConnection.Space» несовместим с «SqlServer.int [Nullable = False, DefaultValue =, StoreGeneratedPattern = Identity]» члена spcID в типе CodeFirstDatabaseSchema.Space.

Как вы сопоставите тип данных для них с длинной переменной в .NET?

Изменить

Прямо сейчас у меня есть простой тест интеграции, чтобы убедиться, что я могу подключиться:

[TestMethod]
public void TestMethod1() {
    using (var context = new Context()) {
        Assert.IsTrue(context.Spaces.Any());
        Assert.IsTrue(context.Spaces.First().IsActive);
    }
}

Без .HasColumnType("int") первый Assert проходит, но я получаю InvalidOperationException на втором:

Свойству «ID» в «Пробел» не может быть присвоено значение «System.Int32». Вы должны установить для этого свойства ненулевое значение типа System.Int64.


person krillgar    schedule 27.12.2013    source источник
comment
Без .HasColumnType(...) работает? Я помню, как использовал EF4 и никогда не использовал ограничение, казалось, отлично работает сопоставление SQL int со значениями long C #.   -  person Erik    schedule 27.12.2013
comment
См. Мою правку выше.   -  person krillgar    schedule 27.12.2013
comment
Я не понимаю, в чем проблема. Если вы используете int в SQL, используйте int в C #. Если вы используете bigint в SQL, используйте long в C #. Оба они имеют одинаковый диапазон значений; см. ответ Тревора.   -  person Dave Zych    schedule 27.12.2013
comment
Глядя на ответ Тревора, похоже, что наше соглашение о int в базе данных и long в C # было неправильным. В лучшем случае это защита уровня данных в будущем.   -  person krillgar    schedule 27.12.2013
comment
Если вы пытаетесь ориентироваться на будущее, почему бы не сделать и то и другое _1 _ / _ 2_? Глупо иметь одного int, а другого long. Что произойдет, если вы превысите значение, которое может удерживать int? Ваш код запускается, но вылетает, когда вы пытаетесь сохранить его в базе данных - и это проблема.   -  person Dave Zych    schedule 27.12.2013
comment
О, я полностью согласен. Как я сказал в ответе Тревора, мне сказали, что SQL int имеет гораздо больший диапазон. Я просто излагаю причины, которые мне дали. Тот факт, что эти причины неверны, меняет мои взгляды на них, и я перестану их защищать.   -  person krillgar    schedule 27.12.2013


Ответы (1)


Типы данных C # и SQL совместимы:

Если в вашей таблице есть столбец bigint, используйте public long Id { get; set; }, если ваш столбец int, используйте public int Id { get; set; }

SQL

bigint от -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807 int от -2,147,483,648 до 2,147,483,647

C #

длинные -9,223,372,036,854,775,808 до 9,223,372,036,854,775,807 целые -2,147,483,648 до 2,147,483,647

Использованная литература:

person Trevor Pilley    schedule 27.12.2013
comment
Интересный! Могу поклясться, что у них разные минимальные / максимальные значения. Спасибо за это. - person Erik; 27.12.2013
comment
@SiLo, зачем им это? Это либо 32-битное, либо 64-битное значение. - person Dave Zych; 27.12.2013
comment
В ПОРЯДКЕ. Это заставляет меня интересоваться эффективностью стандартов моей компании. Возможно, уровень данных ориентирован на будущее, и если они достигнут предела в базе данных, они изменят столбец. Я с @SiLo и подумал, что у них разные минимальные / максимальные значения. - person krillgar; 27.12.2013
comment
@krillgar - int в базе данных и long в классе - это не будущая проверка кода - это бомба замедленного действия! - person Trevor Pilley; 27.12.2013
comment
Согласованный. Я считаю, что идея заключалась в том, что запустить обновление столбца в базе данных легко, а развертывание новой библиотеки DLL - это большая работа. Однако это определенно не лучшая практика. - person krillgar; 27.12.2013
comment
bigint использовать общедоступный длинный идентификатор {получить; набор; } хорошо, что сработало - person Tom Stickel; 22.08.2015
comment
Есть одна проблема (по крайней мере, с ядром EF - если я использую модели, которые имеют long Id, но в базе данных есть идентификаторы int, EF выдает Unable to cast object of type 'System.Int32' to type 'System.Int64'. Это странно, почему бы просто не преобразовать его автоматически в более высокий тип? Думаю, мне придется добавлять вручную привязки идентификаторов везде для рассматриваемой базы данных. - person JustAMartin; 21.06.2019