none
Problema con LINQ, Result type=None RRS feed

  • Pregunta

  • Tengo el seguiente problema con un stored procedure en un sistema usando LINQ,

    el objeto se crea con un result type=none cuando el result type=autogenerated type

    Ahora el storeprocedure es este

    procedure spSelectRevisionesPromDistritoxFecha
    
    @distrito int,
    
    @fechaini smalldatetime,
    
    @fechafin smalldatetime,
    
    @tipo int
    
    As
    
    
    
    declare @value1 float
    
    declare @value2 float
    
    declare @value3 float
    
    
    
    if @distrito=0
    
    begin
    
    	Select @value1= count(revclave)  from priRevisiones,priRestaurante
    
    	where revTipo=@tipo
    
    	and revrestaurante=resclave
    
    	and revfechainicio between @fechaini and @fechafin
    
    
    
    	Select @value2= sum(revcalificacion)  from priRevisiones,priRestaurante
    
    	where revTipo=@tipo
    
    	and revrestaurante=resclave
    
    	and revfechainicio between @fechaini and @fechafin
    
    end
    
    else
    
    begin
    
    	Select @value1= count(revclave)  from priRevisiones,priRestaurante
    
    	where revTipo=@tipo
    
    	and revrestaurante=resclave
    
    	and resdistrito=@distrito
    
    	and revfechainicio between @fechaini and @fechafin
    
    
    
    	Select @value2= sum(revcalificacion)  from priRevisiones,priRestaurante
    
    	where revTipo=@tipo
    
    	and revrestaurante=resclave
    
    	and resdistrito=@distrito
    
    	and revfechainicio between @fechaini and @fechafin
    
    end	
    
    
    
    	if @value1>0
    
    	begin
    
    	set @value3=coalesce(@value2,0)/@value1
    
    	end
    
    	else
    
    	begin
    
    	set @value3=0
    
    	end
    
    	Select @value3 as promedio


    Originalmente tenia un return al final que efectivamente sacaba un entero, pero con el nuevo esta comprobado en el sql que saca un valor flotante.

    Aun peor.

    La clase  spSelectRevisionesPromDistritoxFechaResult no se crea por lo tanto se puede accesar de manera correcta al resultado de ese sp, solo te da el return de si el sp tuvo exito(0 en caso de exito).

    Si la clase la creas a mano y modificas la referencia al sp, el compilador lo cambia a como lo puso originalmente, esto es borra la clase dada de alta de manera manual ylas modificaciones.

    Quisiera saber porque sucede esto, tengo otros store procedures parecidos y no tengo ningun problema con esos.

    Solo aquellos que originalmente tenian un return en su momento.

    A todo esto ya borre los returns y borre el dbml dos veces y nada..sigue igual.



    /*Solucion*/

    Ok al parecer el problema es la manera en que LINQ predice el tipo de resultado basado en la posible salida de un store procedure, si el store procedure parece que va tener diferenres salidas (al parecer el mio lo entiende asi) no puede predecir el tipo del resultado y lo marca como none.

    La solucion es muy sencilla. De hecho si se fijan en el codigo generado por el dbml ya tienen la mitad de la respuesta.

    En dicho codigo hay dos partes, una la declaracion de la clase parcial del dbml y la otra de las tablas y clases xxxResult que no son mas que las clases de los storeprocedures que estamos agregando al dbml.

    En la declaracion parcial viene las declaraciones de las funciones de los store procedures.

    Como este codigo se autogenera con cada compilacion no se puede modificar, pero lo que si se puede hacer es crear otra clase parcial del mismo dbml

    Imports System.Data.Linq
    Imports System.Data.Linq.Mapping
    Imports System.Reflection
    
    Partial Public Class XXXDataContext
        <FunctionAttribute(Name:="dbo.spSelectRevisionesPromDistritoxFecha")> _
        Public Function spSelectRevisionesPromDistritoxFecha(<Parameter(DbType:="VarChar(20)")> ByVal distrito As Integer, <Parameter(DbType:="SmallDateTime")> ByVal fechaini As System.Nullable(Of Date), <Parameter(DbType:="SmallDateTime")> ByVal fechafin As System.Nullable(Of Date), <Parameter(DbType:="Int")> ByVal tipo As System.Nullable(Of Integer)) _
        As ISingleResult(Of spSelectRevisionesPromDistritoxFechaResult)
            Dim result As IExecuteResult = Me.ExecuteMethodCall(Me, CType(MethodInfo.GetCurrentMethod, MethodInfo), distrito, fechaini, fechafin, tipo)
            Return CType(result.ReturnValue, ISingleResult(Of spSelectRevisionesPromDistritoxFechaResult))
        End Function
    End Class
    
    Partial Public Class spSelectRevisionesPromDistritoxFechaResult
    
        Private _promedio As System.Nullable(Of Double)
    
        Public Sub New()
            MyBase.New()
        End Sub
    
        <Column(Storage:="_promedio", DbType:="Float")> _
        Public Property promedio() As System.Nullable(Of Double)
            Get
                Return Me._promedio
            End Get
            Set(ByVal value As System.Nullable(Of Double))
                If (Me._promedio.Equals(value) = False) Then
                    Me._promedio = value
                End If
            End Set
        End Property
    End Class
    De esta manera se soluciona el problema declarando de manera manual la funcion y la clase resultante.

    De hecho de manera muy parecida se pueden declarar store procedures con diferentes tipos de salidas.

    • Editado venom_aa martes, 23 de junio de 2009 21:40
    sábado, 20 de junio de 2009 0:02