问题
If I had a class defined with this attributes
public class GestionesDataSet
{
public DateTime GestionInicio { get; set; }
public DateTime GestionFin { get; set; }
public Nullable<DateTime> LlamadaInicio { get; set; }
public Nullable<DateTime> LlamadaFin { get; set; }
public string Login { get; set; }
public string Tipificacion { get; set; }
public List<CamposGestion> campoValor { get; set; }
}
And the class called CamposGestion is defined like this
public class CamposGestion
{
public string Nombre { get; set; }
public string Valor { get; set; }
}
How can I Defined a report where I can use the field that refers to the list of the other elements?
I tried to used one dataset where I can set this linq as object data source
var gestiones = (from G in db.Gestion
where
G.IDTipificacion == idTipificacion
&& (from T in db.Tipificacion where T.IdTipificacion == G.IDTipificacion select T.Servicio.IDServicio).AsEnumerable().Contains(idServicio)
select G).AsEnumerable().Select(xx => new GestionesDataSet()
{
GestionInicio = xx.HoraInicio,
GestionFin = xx.HoraFin,
@Tipificacion = ((from T in db.Tipificacion select T).Where(x => x.IdTipificacion == xx.IDTipificacion).Count() > 0 ?
(from T in db.Tipificacion where T.IdTipificacion == xx.IDTipificacion select T.Nombre).FirstOrDefault() : ""),
LlamadaInicio = xx.Llamada.HoraInicio,
LlamadaFin = xx.Llamada.HoraFin,
Login = xx.Llamada.Sesion.Usuario.Nombre,
campoValor = xx.CampoValor.Select(aux => new CamposGestion() {
Nombre = aux.ConfiguracionCampo.Campo.Nombre,
Valor = aux.Valor
}).ToList()
}).ToList();
But what I want to see the report the field that contains the List
show's an error like this
Any help would be appreciate.
回答1:
I would rewrite the query like this:
var gestiones =
from xx in db.Gestion
where
xx.IDTipificacion == idTipificacion
&& (from T in db.Tipificacion
where T.IdTipificacion == xx.IDTipificacion select T.Servicio.IDServicio).AsEnumerable().Contains(idServicio)
select new GestionesDataSet()
{
GestionInicio = xx.HoraInicio,
GestionFin = xx.HoraFin,
@Tipificacion = (from T in db.Tipificacion where T.IdTipificacion == xx.IDTipificacion select T.Nombre).FirstOrDefault() ?? "",
LlamadaInicio = xx.Llamada.HoraInicio,
LlamadaFin = xx.Llamada.HoraFin,
Login = xx.Llamada.Sesion.Usuario.Nombre,
campoValor = xx.CampoValor.Select(aux => new CamposGestion()
{
Nombre = aux.ConfiguracionCampo.Campo.Nombre,
Valor = aux.Valor
}).ToList()
}).ToList();
When you call a projection (Select) after the AsEnumerable
was called, LINQ will try to get the navigation objects first from the already loaded ones. If no object is loaded, then will execute a select SQL command for each navigation property used in the projection. If the [DeferredLoadingEnabled][1]
property is set to false
it won't execute any query and if no object is loaded already (they can be loaded "apriori" with [LoadWith][2]
) it will give a NullReferenceException
. So, in some situations, calling AsEnumerable might hurt performance. All these things are not valid when AsEnumerable
is used in the where parts.
For giving a default value, when no Tipificacion
doesn't exist, it can be used the null-coalescing operator, from C#, instead of using the Count
method, which creates an extra lookup on the the table.
Now.. to your problem.
SSRS doesn't support binding to a list of items. The column campoValor tries to bind to a list of objects, which is not allowed. So either you create a subreport (there is a section which describes this) or you flatten your data (having the all the properties on one single object) and then use the HideDuplicates property
来源:https://stackoverflow.com/questions/9637818/handle-this-object-datasource-on-reporting-services