3

Possible Duplicate:
Dynamic Anonymous type in Razor causes RuntimeBinderException

I have this Linq Agregate Query

var GruposQ = from lcGrupos in db.Merlin_ConceptosFacturacion_Kit_Componentes
    where lcGrupos.NumIdConcepto == Item.NumIdConcepto & lcGrupos.BitComponenteVariable == true
    select lcGrupos;

var GruposList = from comps in GruposQ
     group comps by
     new
     {
         NumIdGrupoProducto = comps.NumIdGrupoProducto,
     } into g
     select new
     {
         NumIdTransaccion = NumIdTransaccion,
         NumIdGrupoProducto = g.Key.NumIdGrupoProducto,
         NumCantidad = g.Sum(x=>x.NumCantidad),
         Grupo = GruposQ.Where(x => x.NumIdGrupoProducto == g.Key.NumIdGrupoProducto)
     };


ViewBag.CompsKit = GruposList.ToList();

My problem is when I try to get elements from ViewBag.CompsKit:

@foreach (var myTrans in ViewBag.CompsKit)
{
    // Here it throws an error
    // 'object' does not contain a definition for 'NumIdtransaccion'

    <span>myTrans.NumIdtransaccion</span>
}

But if i look into this object it allready has the property.

myTrans { NumIdTransaccion = 15460
            , NumIdGrupoProducto = 163
            , NumCantidad = 100,000
            , Grupo = System.Data.Common.Internal.Materialization.CompensatingCollection`1[ParadigmaNet.Areas.Items.Models.Merlin_ConceptosFacturacion_Kit_Componentes] }   dynamic {<>f__AnonymousType7<decimal,decimal?,decimal,System.Linq.IQueryable<ParadigmaNet.Areas.Items.Models.Merlin_ConceptosFacturacion_Kit_Componentes>>}

How can I do to access the properties ? in this agregate ?

Community
  • 1
  • 1
Juan Pablo Gomez
  • 5,203
  • 11
  • 55
  • 101

2 Answers2

1

You can't use "dynamic" type in a Razor View.

You must use a typed object as Model.

fred
  • 465
  • 2
  • 7
  • 1
    I think you mean *anonymous type*, not *dynamic*. – sloth Dec 19 '12 at 15:51
  • dynamic is not wrong but anonymous is good too ;-) http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(dynamic_CSharpKeyword);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5);k(DevLang-csharp)&rd=true – fred Dec 19 '12 at 15:55
  • 1
    Yeah, but the OP creates an anonymous type in his code, [and that's his problem](http://stackoverflow.com/questions/5120317/dynamic-anonymous-type-in-razor-causes-runtimebinderexception/5670899#5670899) – sloth Dec 19 '12 at 15:56
  • I'm trying to implement Dominik Kexel solution, but really I don't know where to put the extension. I have the code but when try to apply **.ToExpando()** , compiler doesn't recognize it. – Juan Pablo Gomez Dec 19 '12 at 19:43
1

You can do grouping and filtering in single query:

var numIdConcepto = Item.NumIdConcepto;
var query = from comps in db.Merlin_ConceptosFacturacion_Kit_Componentes
            where comps.NumIdConcepto == numIdConcepto &&
                  comps.BitComponenteVariable
            group comps by comps.NumIdGrupoProducto into g
            select new 
            {
               NumIdGrupoProducto = g.Key,
               NumCantidad = g.Sum(x => x.NumCantidad),
               Grupo = g.ToList()
            };        


ViewBag.CompsKit = query.ToList();
ViewBag.NumIdTransaccion = NumIdTransaccion;

Also

  • you don't need create anonymous object for grouping by single property
  • you don't need to compare boolean values with true/false
  • you can simply use g.Key when use single property for grouping
  • items in group already will have NumIdGrupoProducto equal to grouping key
  • Instead of assigning same NumIdTransaccion to each group in the query result, pass that value to view separately: ViewBag.NumIdTransaccion = NumIdTransaccion

View:

<span>ViewBag.NumIdTransaccion</span>

@foreach(var item in ViewBag.CompsKit)
{
    <span>@item.NumIdGrupoProducto</span>
    <span>@item.NumCantidad</span>
}

Consider also creating ViewModel for this view - thus you will be safe about typos and all such errors will be eliminated at compile time.

Sergey Berezovskiy
  • 232,247
  • 41
  • 429
  • 459