Съпоставяне на свойство на дълги данни към int в база данни

Във всички примери, които съм виждал, използвайте int32s като идентификатори. Това не винаги е практично в производствени среди. Няколко от нашите бази данни имат идентификационни номера, които са в сферата на int64s, така че нашата практика е винаги да използваме long за нашите ID свойства. Въпреки това SQL Server има по-високи максимални стойности за типа колона int.

Правя нашето първо доказателство за концепция с Entity Framework версия 6. С long ID не може да картографира обекта към базата данни.

Използвам Fluent API за цялото си картографиране. В момента това изглежда така за ID:

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“ на „Space“ не може да бъде зададено на стойност „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
Ако се опитвате да бъдете устойчиви на бъдещето, защо и двете не бъдат long/bigint? Тъпо е един да е int, а друг long. Какво се случва, когато надхвърлите стойността, която int може да съдържа? Вашият код работи, но се срива, когато се опитате да го запазите в базата данни - и това е проблем.   -  person Dave Zych    schedule 27.12.2013
comment
О, напълно съм съгласен. Както казах под отговора на Тревър, казаха ми, че int на SQL има много по-голям диапазон. Просто давам причините, които ми бяха посочени. Фактът, че тези причини са неправилни, променя възгледите ми за тях и ще спра да ги защитавам.   -  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 int -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 use public long Id { get; комплект; } хубаво, че работи - 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