views:

98

answers:

1

Hello,

1) I've a Product table with 4 columns: ProductID, Name, Category, and Price. Here's the regular linq to query this table.

public ActionResult Index()
{
  private ProductDataContext db = new ProductDataContext();
  var products = from p in db.Products
                 where p.Category == "Soccer"
                 select new ProductInfo { Name = p.Name, Price = p.Price}
  return View(products);
}

Where ProductInfo is just a class that contains 2 properties (Name and Price). The Index page Inherits ViewPage - IEnumerable - ProductInfo. Everything works fine.

2) To dynamicaly execute the above query, I do this:

Public ActionResult Index()
{
  var products =
                 db.Products
                 .Where("Category = \"Soccer\"")
                 .Select(/* WHAT SOULD I WRITE HERE TO SELECT NAME & PRICE?*/)
  return View(products);
}

I'm using both 'System.Lind.Dynamic' namespace and the DynamicLibrary.cs (downloaded from ScottGu blog).

Here are my questions:

  1. What expression do I use to select only Name and Price?
  2. (Most importantly) How do I retrieve the data in my view? (i.e. What type the ViewPage inherits? ProductInfo?)

=================== EDIT

  1. When I write .Select("new(Name, Price)"), I'm able to pass an object to the ViewData's Model property. Unfortunately, in order to use the Viewdata object, I'm asked to cast the Viewdata to a type. But, I do not know how to determine the type to do the casting.

==================== EDIT

Instead of the ViewData's Model property, I'm using simply the ViewData["products"]. To retrieve the content, I just place a IEnumerable cast before the ViewData, like this:

<% foreach(var item in (IEnumerable)ViewData["products"]){%>
   <p><% = Html.Encode(item)%><p>
<%}%>

There are 2 situations:

1) If I select only one column (for instance, Name), everything work fine. 2) If I select more than 1 more columns (Name, Price), I get something like this

{Name=Soccer, Price=19.50}
{Name=Shin Pads, Price=11.59}

Why I just don't get something like

Soccer, 19.50
Shin Pads, 11.59

================================= EDIT April 02 - 05h47 AM

I've define the GetPropertyValue Method (as your response suggets) as static in a static Class that I called 'HelperClass'. Now, this is the way I try to access the value of Name from my object.

<% = Html.Encode(HelperClass.GetPropertyValue(ViewData["product"], "Name")) %>

I get the following Exception:"Object reference not set to an instance of an object". And, the following line from the inside GetPropertyValue() his highlight.

Line 22: return propInfo.GetValue(obj, null);

Do I need to use new keyword? (where?)

Thanks for helping

A: 

1) To generate a new projection type at runtime you can:

.Select("new(Name, Price)")

2) To read values from the object, you need to use reflection:

string name = GetPropertyValue(someObject, "Name");

...

public static object GetPropertyValue(object obj, string propName)
{
    System.Reflection.PropertyInfo propInfo = obj.GetType().GetProperty(propName);
    return propInfo.GetValue(obj, null);
}
KristoferA - Huagati.com
Can you tell me what's obj, propName are? From the code above, can I draw the following inferences: object obj --> products and string propName --> the column (Name, Price)?
Richard77
Should I pass my result 'products' using the ViewData's Model property or just the regular ViewData dictionary? In fact, when I pass products through the Model property, I do not know how to define the type of the object.
Richard77
I edited the answer above to (hopefully) make it more clear.The type is not known at compile time, anonymous projections like the one above from dynamic linq will return types that are generated at runtime. You need to declare as object and then use reflection at runtime to get hold of the values.
KristoferA - Huagati.com
I've tried to use GetPropertyValue, but I'm getting the 'Object not set to an instance of an object' exception (see the latest edit of my question -- April 02 at 05h47')
Richard77