7

Estoy intentando convertir un proyecto que actualmente usa un marco DAO personalizado para usar Entity Framework. El sistema es bastante grande, por lo que los cambios en la base de datos (una base de datos SQL Azure si eso importa) no son particularmente viables y deberían evitarse si es posible.C#: Change Retrieval DataType for Entity Framework

El problema es con la columna ID. Lamentablemente, cuando se creó el sistema, hay algunas tablas que tienen un tipo de datos bigint, y algunas que tienen un int, pero todos los modelos provienen de una clase base que tiene un long para la ID. El marco anterior fue capaz de manejar esta situación, pero no he podido encontrar una manera de hacerlo con el marco de la entidad.

A continuación es el ejemplo más trivial que puedo pensar:

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 | 
| ...   | 
+-------------+ 

Cuando intento cargar un modelo Bar, me sale este error:

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'. 

me gustaría encontrar una forma de decirle al sistema que Bar tiene entradas, mientras que Foo tiene anhelos. Intenté sobreescribir OnModelCreating en el contexto y definir HasColumnType para Bar. Eso me dio un nuevo error:

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'. 

Me parece que si pudiera cambiar el tipo de datos que se espera para el ID de BaseClass a int antes de enviar la solicitud al servidor, entonces yo debería ser capaz de hasta -convertir a long después de recibir la respuesta. Idealmente, me gustaría hacer esto por clase.

¿Alguien puede indicarme la dirección correcta?

Respuesta

4

Mientras que implícitamente puede emitir un bigint to an int in SQL Server, parece que los tipos de electroerosión marco de la entidad (que es realmente lo que usted está tratando con) no permite una transformación implícita de un tipo entero de 64 bits a 32 bits tipo entero

Esto es probablemente por una buena razón, porque podría desbordarse fácilmente y tener valores que no caben en los campos int.

Dicho esto, debe tener dos clases base, una para una ID int y otra para una ID long. No es bonito, pero impone la lógica que definitivamente deseas; no podrá almacenar valores que son más grandes de lo que puede caber en un int en la base de datos, entonces ¿por qué querría poder hacerlo en el nivel de código? El marco de la Entidad está haciendo lo correcto aquí al no permitirle aplicar esa transformación.

+0

Sí - eso es lo que tenía miedo. Reconozco que estoy tratando de corregir un error con otro error. Solo esperaba poder evitar grandes cambios con algunos pequeños trucos. Todo lo que probé terminó no funcionaba, así que creo que me he resignado a hacer exactamente lo que me has recomendado. Si no hay mejores soluciones, lo marcaré como correcto. – Merwer

+0

@Merwer A veces, la verdad duele, por favor no dispares al messenger =) – casperOne

+0

Hola @casperOne Perdón por irrumpir con mi pregunta ya que es sobre el mismo tema. ¿Hay alguna forma de hacer lo opuesto? Tengo una tabla con una identificación de tipo Int. Se está volviendo peligrosamente grande y me pregunto si hay alguna forma de cambiarlo a Long. (Entity Framwork CF 6.1) – hjavaher