i must be doing something wrong or maybe i don't get this. I'm trying to fill 'PropAllMenus' (that has a bunch of properties) with data coming from my entity framework. However, when doing the conversion trough a function i get a 'InvaldCastExeption' in my 'WeekMenuRepository'. Here is the code:
PropAllMenus
Public Class PropAllMenus
Private _MenuID As Integer
Public Property MenuID() As Integer
Get
Return _MenuID
End Get
Set(ByVal value As Integer)
_MenuID = value
End Set
End Property
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _DaypartID As Integer
Public Property DaypartID() As Integer
Get
Return _DaypartID
End Get
Set(ByVal value As Integer)
_DaypartID = value
End Set
End Property
End Class
WeekMenuRepository
Private _db As New EDMWeekmenuEntities()
Public Function ListAllMenus() As IQueryable(Of PropAllMenus) Implements IWeekMenuRepository.ListAllMenus
Dim result = From p In _db.Menus _
Select p
Return result
End Function
HomeController
Dim DoThings As New WeekMenuRepository()
Function Index() As ActionResult
Return View(DoThings.ListAllMenus().ToList)
End Function
PropAllMenus isn't an entity type, so the EF can't implicitly convert an entity type like Menu to it.
In other words, your function result type is IQueryable(Of PropAllMenus), but your query is returning something like ObjectQuery(Of Menu). If you could change your query to return ObjectQuery(Of PropAllMenus) then the implicit cast (when you call Return) to IQueryable would work.
You need to do something like:
Dim result = From p In _db.Menus _
Select New PropAllMenus With
{
.MenuId = p.MenuId,
.Name = p.Name,
// etc.
}
By the way, I noticed that you have asked 6 questions, but have never accepted any answers, nor uploaded anything. You should press the "up arrow" next to any answers which you find helpful, and press the "checkmark" icon next to the single most helpful answer for a question you've asked. It's a way of saying "thank you."
Related
Public Function List_category() As Myobj
Dim query = From subcat In _dataContext.subcategories, _
cat In _dataContext.categories _
Where subcat.CategoryID = cat.CategoryID _
Select New Myobj() With { _
.SubcatId = subcat.SubCategoryID, _
.SubcatName = subcat.SubCategoryName, _
.CatId = cat.CategoryID, _
.CatName = cat.CategoryName _
}
return ?????????
End Function
Public Class Myobj
Private m_SubcatId As Integer
Private m_SubcatName As String
Private m_catId As Integer
Private m_catName As String
Public Property SubcatId() As Integer
Get
Return m_SubcatId
End Get
Private Set(ByVal value As Integer)
m_SubcatId = value
End Set
End Property
Public Property SubcatName() As String
Get
Return m_SubcatName
End Get
Private Set(ByVal value As String)
m_SubcatName = value
End Set
End Property
Public Property CatId() As Integer
Get
Return m_catId
End Get
Private Set(ByVal value As Integer)
m_catId = value
End Set
End Property
Public Property CatName() As String
Get
Return m_catName
End Get
Private Set(ByVal value As String)
m_catName = value
End Set
End Property
End Class
doesnt works!!!!
It Says 'Set' accessor of property 'SubcatName' is not accessible.
You can create a custom type and modify your select to instantiate that for the return. Take a look here: Linq To Sql return from function as IQueryable<T>
Compiler is just telling you that you have declared Private Set on SubcatName and yet ypou are trying to assing a value to it after New Myobj().
For a first run you can declare a POD class (plain old data - just public data, no methods or properties) and once you see it runnung you can go tweaking it, adding methods etc.
If it's really important that all properties are read-only you'll need to try making your querying method a static member of the same class.
Also, there is a way to return anonymous type and cast it back to equivalent anonymous type declared at the receiving side. Got to move on to C# though :-)
Example (read article):
// Method that returns anonymous type as object
object ReturnAnonymous()
{
return new { City="Prague", Name="Tomas" };
}
// Application entry-point
void Main()
{
// Get instance of anonymous type with 'City' and 'Name' properties
object o = ReturnAnonymous();
// This call to 'Cast' method converts first parameter (object) to the
// same type as the type of second parameter - which is in this case
// anonymous type with 'City' and 'Name' properties
var typed = Cast(o, new { City="", Name="" });
Console.WriteLine("Name={0}, City={1}", typed.Name, typed.City);
}
// Cast method - thanks to type inference when calling methods it
// is possible to cast object to type without knowing the type name
T Cast<T>(object obj, T type)
{
return (T)obj;
}
I have a class like
Public Class Task
Property DuplexType As Char
Property Name As String
End Class
In my controller I have an action that looks like
<HttpPost()>
Function Edit(ByVal task As Task) As ActionResult
Dim duplexType = task.DuplexType
Dim valid = ModelState.IsValid
Return RedirectToAction("Index")
End Function
In the view, DuplexType = " " (single space) and Name = "Foo". Why doesn't the property DuplexType have a value? If I assign any other character it works fine.
In the controller name = "foo" but DuplexType = " (empty).
Also ModelState.IsValid = false if DuplexType = " ".
Have a look at the Response object and examine the values being populated by the form Post. You will probably see that values are trimmed and therefore lose the space. If possible try to UrlEncode the values.
Where I have had to preserve trailing spaces in my own projects, I have ended up having to put delimiters on the parameter and then strip them off in the action method.
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:
What expression do I use to select only Name and Price?
(Most importantly) How do I retrieve the data in my view? (i.e. What type the ViewPage inherits? ProductInfo?)
===================
EDIT
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
Private Sub filter()
Dim coll = db.Products.Where(Function(x) x.Category.Equals("Soccer")) _
.Select(Function(x) GetObject(x.Name, x.Price))
End Sub
Private Function GetObject(ByVal name As String, ByVal price As String) As Object
Return new ProductInfo(name, price)
End Function
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);
}
I have a table 'Menus' containing the
names of the menus of the restaurant.
I also have a table 'Ingredients'
containing the ingredients that are
available to the menus.
I don't have any trouble getting the values out of the 'Menus' table into an IQueryable class (PropAllMenus)
Public Class PropAllMenus
Private _MenuID As Integer
Public Property MenuID() As Integer
Get
Return _MenuID
End Get
Set(ByVal value As Integer)
_MenuID = value
End Set
End Property
Private _Name As String
Public Property Name() As String
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
Private _DaypartID As Integer
Public Property DaypartID() As Integer
Get
Return _DaypartID
End Get
Set(ByVal value As Integer)
_DaypartID = value
End Set
End Property
I just use this code in the DBRepository class
Public Function ListAllMenus() As IQueryable(Of PropAllMenus) Implements IDBRepository.ListAllMenus
Dim result = From p In _db.Menus Select New PropAllMenus With {.MenuID = p.MenuID, .Name = p.Name}
Return result
End Function
This works fine.
Now, i also have a many to many
table 'MenuIngredients' containing
the Id's of ingredients that belong
to a menu.
However, i don't know what steps i should take to:
Query the DB with a LINQ query to
get a LIST of MENU NAMES with all
their INGREDIENTS
fill up a new
IQuerable(of...) class so i can pass
it to my view
I tried using a property of type array (that contained the ingredients of a menu) but that didn't seem to work.
YOu just need to add a partial class to your current Menu class like this:
public partial class Books
public property IEnumerable< Ingredient > Ingredients
get
return me. MenuIngredients.Select( function (mi) mi.Ingredient);
end get
end Property
public sub AddIngredient( i as Ingredient )
//do the logic here
End Sub
public sub AddIngredient( i as Ingredient )
//do the logic here
End Sub
End
This then would include the ingredients in to your menu class
I'm trying to write 2 extension methods to handle Enum types. One to use the description attribute to give some better explanation to the enum options and a second method to list the enum options and their description to use in a selectlist or some kind of collection.
You can read my code up to now here:
<Extension()> _
Public Function ToDescriptionString(ByVal en As System.Enum) As String
Dim type As Type = en.GetType
Dim entries() As String = en.ToString().Split(","c)
Dim description(entries.Length) As String
For i = 0 To entries.Length - 1
Dim fieldInfo = type.GetField(entries(i).Trim())
Dim attributes() = DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
description(i) = If(attributes.Length > 0, attributes(0).Description, entries(i).Trim())
Next
Return String.Join(", ", description)
End Function
<Extension()> _
Public Function ToListFirstTry(ByVal en As System.Enum) As IEnumerable
Dim type As Type = en.GetType
Dim items = From item In System.Enum.GetValues(type) _
Select New With {.Value = item, .Text = item.ToDescriptionString}
Return items
End Function
<Extension()> _
Public Function ToListSecondTry(ByVal en As System.Enum) As IEnumerable
Dim list As New Dictionary(Of Integer, String)
Dim enumValues As Array = System.Enum.GetValues(en.GetType)
For Each value In enumValues
list.Add(value, value.ToDescriptionString)
Next
Return list
End Function
So my problem is both extension methods don't work that well together. The methods that converts the enum options to an ienumerable can't use the extension method to get the description.
I found all kind of examples to do one of both but never in combination with each other. What am I doing wrong? I still new to these new .NET 3.5 stuff.
The problem is that Enum.GetValues just returns a weakly typed Array.
Try this:
Public Function ToListFirstTry(ByVal en As System.Enum) As IEnumerable
Dim type As Type = en.GetType
Dim items = From item In System.Enum.GetValues(type).Cast(Of Enum)() _
Select New With {.Value = item, .Text = item.ToDescriptionString}
Return items
End Function
(It looks like explicitly typed range variables in VB queries don't mean the same thing as in C#.)