7

Próbuję przekonwertować projekt, który obecnie korzysta z niestandardowej struktury DAO do korzystania z Entity Framework. System jest dość duży, więc zmiany w bazie danych (SQL Azure DB, jeśli to ważne) same w sobie nie są szczególnie wykonalne i powinny być w miarę możliwości unikane.C#: Zmień typ DataType pobierania dla Entity Framework

Problem dotyczy kolumny ID. Niestety, gdy system został utworzony, istnieją pewne tabele, które mają typ danych bigint, a niektóre z nich mają int - ale same modele pochodzą z klasy bazowej mającej long dla identyfikatora. Poprzednie ramy były w stanie poradzić sobie z tą sytuacją, ale nie byłem w stanie znaleźć sposobu na zrobienie tego za pomocą struktury encji.

Poniżej jest najbardziej trywialny przykład mogę myśleć:

public class Context : DbContext { 
    public IDbSet<Foo> Foos {get;set;} 
    public IDbSet<Bar> Bars {get;set;} 
} 
public abstract class BaseClass { 
    public long ID; 
} 
public class Foo : BaseClass { 
    ... 
} 
public class Bar : BaseClass { 
    ... 
} 
SQL Table: Foo 
+-------------+ 
| id : bigint | 
| ...   | 
+-------------+ 
SQL Table : Bar 
+-------------+ 
| id : int | 
| ...   | 
+-------------+ 

Kiedy próbuję załadować Bar modelu, otrzymuję ten błąd:

The 'ID' property on 'BaseClass' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'Int64'. 

chciałbym znaleźć sposób powiedzieć systemowi, że Bar ma ints, podczas gdy Foo ma długi. Próbowałem zastąpić OnModelCreating w kontekście i definiując HasColumnType dla HasColumnType dla . To dało mi nowy błąd:

Schema specified is not valid. Errors: 
    (105,12) : error 2019: Member Mapping specified is not valid. The type 'Edm.Int64[Nullable=False,DefaultValue=]' of member 'ID' in type 'Bar' is not compatible with 'SqlServer.int[Nullable=False,DefaultValue=,StoreGeneratedPattern=Identity]' of member 'ID' in type 'CodeFirstDatabaseSchema.Bar'. 

Wydaje mi się, że gdybym mógł zmienić tylko oczekiwany typ danych dla ID z BaseClass do int przed wysłaniem żądania do serwera, a następnie powinny być w stanie się -konwertuj do long po otrzymaniu odpowiedzi. Idealnie, chciałbym to zrobić na podstawie klasy.

Czy ktoś może wskazać mi właściwy kierunek?

Odpowiedz

4

Chociaż można niejawnie rzucić bigint to an int in SQL Server, wydaje się, że typy EDM struktury Entity (z którym naprawdę mamy do czynienia) nie pozwalają na niejawną transformację z 64-bitowego typu całkowitego na 32-bitowy typ całkowity.

Jest to prawdopodobnie nie bez powodu, ponieważ można łatwo przepełnić i wartości, które nie mieszczą się w polach int.

Powiedziawszy, powinieneś mieć dwie klasy bazowe, jedną dla identyfikatora int i jedną dla identyfikatora long. Nie jest ładny, ale wymusza logikę, którą zdecydowanie chcesz; nie będziesz w stanie przechowywać wartości większych niż to, które zmieści się w bazie danych, więc dlaczego miałbyś chcieć to zrobić na poziomie kodu? Struktura Entity robi dobrą rzecz, nie pozwalając ci zastosować tej transformacji.

+0

Tak, właśnie tego się obawiałem. Rozumiem, że próbuję naprawić błąd za pomocą innego błędu. Miałem tylko nadzieję, że uda mi się uniknąć wielkich zmian zamiatania za pomocą kilku drobnych sztuczek. Wszystko, co próbowałem, skończyło się nieskutecznie, więc myślę, że zrezygnowałem z robienia dokładnie tego, co poleciłeś. Jeśli nie pojawią się żadne lepsze rozwiązania, zaznaczę to jako prawidłowe. – Merwer

+0

@Merwer Czasami prawda boli, proszę nie strzelać do posłańca =) – casperOne

+0

Witam @ casperOne Przykro mi, że mogę dołączyć do mojego pytania, ponieważ jest to ten sam temat. Czy istnieje sposób na odwrotny skutek? Mam tabelę z identyfikatorem typu Int. Staje się niebezpiecznie duży i zastanawiam się, czy istnieje sposób na zmianę go na Long? (Entity Framwork CF 6.1) – hjavaher

Powiązane problemy