none
Uso de campo discriminador para crear Herencia... Error en condición.. ¿? RRS feed

  • Pregunta

  • Muy buenas,

    Soy nuevo con esto de EF, y estoy realizando unas cuantas pruebas. Os cuento primero la estructura del proyecto, por si os da alguna idea del problema.

    Como base de datos estoy usando SQL Compact Ed.

    Tengo la aplicación separada en 4 proyectos:

    Windows Forms para UI
    Una librería donde está el context, el modelo de EF y los repositorios que de momento necesito
    Una librería con las entidades STE
    Una librería con la lógica del dominio.

    He tenido la aplicación funcionando, pero he querido meter herencia, y me peta el modelo. os cuento:

    Tengo una tabla [TableMappings] donde albergo dos distintos orígenes para realizar una importación de datos: pueden venir mediante ficheros de texto o mediante DataTables que yo luego transformo. La tabla tiene los siguientes campos:

    • TableId
    • ImportMode
    • Source
    • ConnectionString
    • SQLStatement
    • FilePath
    • FileName

    Esa única tabla [TableMappings] la he querido representar en el modelo de entidades de la siguiente manera:

    • Entidad base: TableMappings (TableID, ImportMode, Source)
    • Entidad derivada 1: DataObjectMap (ConnectionString, SQLStatement)
    • Entidad derivada 2: FileMap (FilePath, FileName)
    Estoy usando como campo discriminador, el campo Source, que puede tener sólo dos valores: DataObject o File.

    En la Entidad base, he puesto como condición que Source = Null, por si se diese el caso (que no se va a dar, son excluyentes).

    En cada condición derivada, he puesto respectivamente: Source = DataObject, Source = File.

    El campo Source es nvarchar(15) y admite nulos.

    Y bueno, después de esta parrafada... compilo la solución y... tachaaan!! peaso de error:

    Error    1    Error 3032: Hay un problema con los fragmentos de asignación a partir de la línea 164:Se ha asignado el miembro de la condición 'TableMapping.Source' con una condición distinta de 'IsNull=False'. Quite la condición en TableMapping.Source o quítela de la asignación.
        C:\Users\achamorro\Documents\My Dropbox\Proyectos\MSS Data Transfer\Infraestructure.Data\Model\MssDtDataModel.edmx    165    15    Infraestructure.Data

    Si me voy a ver el modelo en formato XML, veo lo siguiente en la sección C-S:

    <EntitySetMapping Name="TableMappings">
          <EntityTypeMapping TypeName="IsTypeOf(Infrastructure.Data.MssDt.Model.DataObjectMap)">
           <MappingFragment StoreEntitySet="TableMapping">
            <ScalarProperty Name="Source" ColumnName="Source" />
            <ScalarProperty Name="TableID" ColumnName="TableID" />
            <ScalarProperty Name="SQLStatement" ColumnName="SQLStatement" />
            <ScalarProperty Name="ConnectionString" ColumnName="ConnectionString" />
            <ScalarProperty Name="ImportMode" ColumnName="ImportMode" />
            <Condition ColumnName="Source" Value="DATAOBJECT" />
           </MappingFragment>
          </EntityTypeMapping>
          <EntityTypeMapping TypeName="Infrastructure.Data.MssDt.Model.TableMapping">
           <MappingFragment StoreEntitySet="TableMapping">
            <ScalarProperty Name="TableID" ColumnName="TableID" />
            <ScalarProperty Name="Source" ColumnName="Source" />
            <ScalarProperty Name="ImportMode" ColumnName="ImportMode" />
            <Condition ColumnName="Source" IsNull="true" />
           </MappingFragment>
          </EntityTypeMapping>
          <EntityTypeMapping TypeName="IsTypeOf(Infrastructure.Data.MssDt.Model.FileMap)">
           <MappingFragment StoreEntitySet="TableMapping">
            <ScalarProperty Name="ImportMode" ColumnName="ImportMode" />
            <ScalarProperty Name="Source" ColumnName="Source" />
            <ScalarProperty Name="TableID" ColumnName="TableID" />
            <ScalarProperty Name="FileName" ColumnName="FileName" />
            <ScalarProperty Name="FilePath" ColumnName="FilePath" />
            <Condition ColumnName="Source" Value="File" />
           </MappingFragment>
          </EntityTypeMapping>
         </EntitySetMapping>
    

    Y la verdad... quizá he empezado la casa por el tejado... no se. El caso es que según he estado leyendo, parece más sencillo... y ya no se por dónde seguir.

    Así que, si a alguien se le ocurre algo, muchísimas gracias de antemano

    Un saludo, Antonio.

    lunes, 13 de diciembre de 2010 15:46

Respuestas

  • Muy buenas de nuevo.

    He conseguido que el proyecto vuelva a compilar. El error que estaba cometiendo es que estaba incluyendo el campo discriminador ([TableMapping].[Source]) como parte de la entidad base TableMapping. Al quitarlo de la asignación, la herencia ha funcionado y todo vuelve a su sitio!

    Efectivamente, no tiene sentido incluir ese campo como propiedad en la entidad base, ya que nunca se le va a dar valor de manera explícita... o eso creo yo...

    Así que ahora, a grabar esa peaso de jerarquía de herencia!!

    Gracias a todos!

    • Marcado como respuesta Antonio Chamorro miércoles, 15 de diciembre de 2010 16:35
    martes, 14 de diciembre de 2010 11:31

Todas las respuestas

  • Hola Antonio,

    ¿podrías publicar el código para echarle un vistazo? Posiblemente tengas algún problema en la configuración del mapping o con alguna campo Nullable que no lo debería de ser.


    Alberto Diaz Martin twitter://@adiazcan | http://geeks.ms/blogs/adiazmartin
    lunes, 13 de diciembre de 2010 19:21
  • Hola Alberto,

     

    Gracias por tu respuesta, ¿qué codigo necesitas? puedo preparar un script de base de datos para recrearla, y el resto puedo pasar una parte... humm.. voy a ver que puedo sacar.
    Por otro lado, el campo Source, que es el que me discrimina las dos entidades derivadas, admite nulos... 

    Lo he cambiado a integer, que admite el valor 1 - DataObject y 2 - File.

    Por otro lado, esta tarde dándole vueltas al tema, me ha surgido una duda, que me ha hecho plantearme la aproximación que estoy haciendo, a ver si me explico:

    Necesito guardar en base de datos las nuevas entidades (DataObjectMap y FileMap) que el usuario de de alta... y no se si plantear un modelo con Herencia me va a permitir hacerlo de una manera sencilla, ya que entiendo que para guardar una entidad FileMap (por ejemplo) tendré que dar valores a su entidad padre ¿no?

    O eso, o personalizar el alta de ese tipo de entidades en base de datos... no se si me explico bien.

    Bueno, voy a ver si me ilumino un poco...

    Gracias!

     

     

    lunes, 13 de diciembre de 2010 23:40
  • Hola Antonio

    voy a intentar buscar un hueco y te preparo un ejemplo de herencia con discriminador para que lo veas. Lo del alta es sencillo, piensa que las entidades que heredan tienen todos los campos que necesitan y que son obligatorios para ella (los suyos y los del padre)


    Alberto Diaz Martin twitter://@adiazcan | http://geeks.ms/blogs/adiazmartin
    martes, 14 de diciembre de 2010 8:21
  • Hola Alberto,

    Mil gracias, de verdad. En los tiempos que corren no es facil para nadie sacar un hueco y echar un cable. yo por mi parte voy a seguir leyendo e investigando... contaré por aqui cualquier avance.

    Gracias!

    martes, 14 de diciembre de 2010 9:51
  • Muy buenas de nuevo.

    He conseguido que el proyecto vuelva a compilar. El error que estaba cometiendo es que estaba incluyendo el campo discriminador ([TableMapping].[Source]) como parte de la entidad base TableMapping. Al quitarlo de la asignación, la herencia ha funcionado y todo vuelve a su sitio!

    Efectivamente, no tiene sentido incluir ese campo como propiedad en la entidad base, ya que nunca se le va a dar valor de manera explícita... o eso creo yo...

    Así que ahora, a grabar esa peaso de jerarquía de herencia!!

    Gracias a todos!

    • Marcado como respuesta Antonio Chamorro miércoles, 15 de diciembre de 2010 16:35
    martes, 14 de diciembre de 2010 11:31
  • Pues sí, no tiene sentido. Piensa que la entidad de la que heredan debería de ser capaz de comportarse como una entidad independiente de las otras.

     


    Alberto Diaz Martin twitter://@adiazcan | http://geeks.ms/blogs/adiazmartin
    martes, 14 de diciembre de 2010 12:07
  • Y digo yo, ¿tiene que ver en ese comportamiento que el campo Source admita nulos? porque la verdad no se me ocurre otra cosa...

    Gracias de nuevo!

    martes, 14 de diciembre de 2010 13:51