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#.)
Related
Im trying to add a filter to a MVC with a multiple LINQ query that i got from This Question and i want to make a filter like "add Genre" on this which is a dropdownlist Tutorial if i take off the parameter from the function of brand (i do get my dropdownlist working) And the thing is that im not sure, because in the table i need to filter brand is a number (so i think i need to pass that parameter as integer), however i get an error
"The parameters dictionary contains a null entry for parameter 'brand' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(System.String, System.String, System.String, System.Nullable`1[System.Int32], Int32)' in 'BDInventario.Controllers.ArticulosController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters"
Below is my code
Function Index(ByVal sortOrder As String, currentFilter As String, ByVal searchString As String, page As Integer?,brand as Integer) As ActionResult
ViewBag.CurrentSort = sortOrder
ViewBag.NameSortParm = If(String.IsNullOrEmpty(sortOrder), "name_desc", String.Empty)
If Not searchString Is Nothing Then
page = 1
Else
searchString = currentFilter
End If
ViewBag.CurrentFilter = searchString
Dim brandList As New List(Of String)
Dim brandQuery = From a In db.Articulos
Join m In db.Articulo_brand On a.brand_id Equals m.brand_id
Order By m.desc_brand
Select m.desc_brand
brandList.AddRange(brandQuery.Distinct)
ViewBag.brand = New SelectList(brandList)
Dim articulos = From m In db.Articulos Select m
Select Case sortOrder
Case "name_desc"
articulos = articulos.OrderByDescending(Function(s) s.descripcion)
Case Else
articulos = articulos.OrderBy(Function(s) s.articulo_id)
End Select
If Not String.IsNullOrEmpty(searchString) Then
articulos = articulos.Where(Function(Inventario_ADO) Inventario_ADO.descripcion.Contains(searchString))
End If
I think my error is in this section
If Not String.IsNullOrEmpty(brand) Then
articulos = articulos.Where(Function(m) m.brand_id.Equals(brand))
End If
Dim pageSize As Integer = 50
Dim pageNumber As Integer = If(page, 1)
Return View(articulos.ToPagedList(pageNumber, pageSize))
End Function
Any help or tips would be really apreciated
The error is because your brand parameter must be a nullable integer, like the page parameter is.
Also, I would do the ordering after the filtering. And you use ViewBag a lot, why not a ViewModel?
I am getting an arraylist in view from controller. In view when i try to display that array error occur "Unable to cast object of type 'System.Collections.ArrayList' to type 'System.Collections.Generic.IList`1". my code is as below
Dim c As IList(Of myclass) = CType(Model, IList(Of myclass)) (arraylist from controller)
In Model there is an arraylist. I don't know how to cast this arraylist into IList. Please help. Thanks
Dim iplist = (From d In db.mytable Select d).ToList
Dim c2 As ArrayList
For i As integer = 0 to iplist.Count - 1
Dim ip = iplist(i).ip
Dim c as countrylist
c.country = country
c.city = city
Next
Class cou1ntrylist
Public country As String
Public city As New ArrayList
End Class
I have the following code :
public class ComputeOperationData
{
public COUNTERS_DATA CounterData { get; set; }
public COMPUTES_OPERATION ComputeOperation { get; set; }
public COUNTERS_FORMULA CounterFormula { get; set; }
}
Public Function GetComputeOperationData(ByVal computeId As Integer, ByVal priodType As Integer, ByVal lstDuringTime As DuringTime) As IList(Of ComputeOperationData) Implements IComputeResultService.GetComputeOperationData
Dim computeOperations As IQueryable(Of COMPUTES_OPERATION) = _repository.GetObjectQuery(Of COMPUTES_OPERATION).Include("COMPUTES").Include("COUNTERS")
computeOperations = computeOperations.Where(Function(a) a.COMPUTE_ID = computeId)
Dim countersFormula As IQueryable(Of COUNTERS_FORMULA) = _repository.GetObjectQuery(Of COUNTERS_FORMULA)().Include("COUNTERS")
Dim countersData As IQueryable(Of DomainClasses.COUNTERS_DATA) = _repository.GetObjectQuery(Of DomainClasses.COUNTERS_DATA)().Include("COUNTERS")
countersData = countersData.Where(Function(a) a.PERIOD_TYPE = priodType And a.COUNTER_DATE = lstDuringTime.StartDate And a.COUNTER_TIME >= lstDuringTime.StartTime And a.COUNTER_TIME <= lstDuringTime.EndTime)
Dim lstComputeOperationData = From counterData In countersData
Join computeOperation In computeOperations On counterData.COUNTER_ID Equals computeOperation.COUNTER_ID
Join counterFormula In countersFormula On counterData.COUNTER_ID Equals counterFormula.COUNTER_ID
Where counterData.COUNTER_DATE >= counterFormula.FROM_DATE And counterData.COUNTER_DATE <= counterFormula.TO_DATE
Return lstComputeOperationData.ToList
End Function
And I got this error :
Unable to cast object of type 'System.Data.Objects.ObjectQuery1[VB$AnonymousType_13[Danesh.Ems.DomainClasses.COUNTERS_DATA,Danesh.Ems.DomainClasses.COMPUTES_OPERATION,Danesh.Ems.DomainClasses.COUNTERS_FORMULA]]' to type 'System.Collections.Generic.IList`1[Danesh.Ems.Models.ComputeOperationData]'
please help me
It's been a while since I used VB.NET, but in C#, you'd need something like...
Select New ComputeOperationData()
{
CounterData = counterData, ComputeOperation = computeOperation, CounterFormula = counterFormula
}
...at the end of your query to transform the three separate data sources into a single object.
You have function that return IList(Of ComputeOperationData) but inside you tru return List(Of AnonymousClass)
so in your linq query you need specify what type of object you want return, like this
Dim lstComputeOperationData = From counterData In countersData
Join computeOperation In computeOperations On counterData.COUNTER_ID Equals computeOperation.COUNTER_ID
Join counterFormula In countersFormula On counterData.COUNTER_ID Equals counterFormula.COUNTER_ID
Where counterData.COUNTER_DATE >= counterFormula.FROM_DATE And counterData.COUNTER_DATE <= counterFormula.TO_DATE
Select New ComputeOperationData With {.CounterData = counterData, .ComputeOperation = computeOperation, .CounterFormula = counterFormula}
When you see the runtime error message: Unable to cast object of type Generic.List [SomeDerivedType] to Generic.IList[SomeBaseType], you may simply need to Cast the objects to the proper type in the list before making the assignment to the IList.
For example:
Dim objectIList As IList(Of Object)
Dim stringList As New List(Of String)
objectIList = stringList.Cast(Of Object).ToList()
This is tricky because the compiler does not catch this. There are several C# based questions that relate to this issue. Here is one. Here is another.
MVC 3 razor VB.NET project. I have resorted to manual building a list for a drop down box so I can insure certain values are available in the select list and also to control what the first item is in the list. The below is my code snippet for the part that is giving me problems..
Dim _courses1 As Integer = db.courses.ToList.Where(Function(r) r.course_day = "Tuesday").Count
Dim _classes1 As List(Of cours) = db.courses.ToList
Dim classRef1 As List(Of String)
If Not _selectedClass0 = "--" Then
classRef1.Add("--")
Else
classRef1.Add(_selectedClass0)
End If
For i As Integer = 0 To _courses1 - 1
For Each item In _classes1.Where(Function(f) f.course_day = "Tuesday")
Dim _item As cours = item
classRef1.Add(_item.course_ref)
Next
Next
ViewBag.tue1 = classRef1
The _selectedClass0 is just a string that gets set earlier... The error mentioned happens when it gets to the ClassRef1.Add(_selectedClass0) part of the else statement. Which _selectedClass0 string value at the time of error is "--". I have a feeling it is in how the list is being created but I am not certain... Any ideas???
You're not initializing classRef1.
Dim classRef1 As new List(Of String)
Another thing I see is in the first line - I've made the changes I see:
Dim _courses1 As Integer = db.courses.Where(Function(r) r.course_day = "Tuesday").Count()
You don't need ToList at the beginning if all your getting is the count.
You are declaring classRef1 to be a list of strings here:
Dim classRef1 As List(Of String)
But you're never actually creating an instance using New. I'm not sure about the VB syntax, as I'm a C# developer, but I'd guess you should add the following line right after the declaration:
classRef1 = New List(Of String)
I am using a where comparer in the below snippet from my function.. I need to order or sort the returned items by one of the columns... I tried using .OrderBy(function(f) f.regDate) but that dont work at all...
The part of the function in question looks like this:
Function ClassFiller() As ActionResult
Dim _courses As List(Of cours) = db.courses.ToList
Dim _registrants As List(Of reg_info) = db.reg_info.ToList
Dim _classSpec As List(Of classrm) = db.classrms.ToList
Dim _CurrRegistrants As List(Of reg_classes) = db.reg_classes.ToList
For Each Course In _courses.Where(Function(a) a.course_day = "Tuesday")
Dim _CurrCourse As cours = Course
Dim _classRoom As classrm = db.classrms.Where(Function(b) b.Course_ID = _CurrCourse.course_ref).FirstOrDefault()
Dim _classmax As Integer = _classRoom.ClassMax - 1
For Each reg In _registrants.Where(Function(d) d.tues_class1 = _CurrCourse.course_ref).OrderBy(Function(f) f.reg_date)
Dim _ClassCount As Integer = db.reg_classes.Where(Function(c) c.tues_class = _CurrCourse.course_ref).Count
I need to have the _registrants ordered or sorted by a value that is in the db.reg_info under the reg_date column... Any ideas??
Where _registrant is declared at I should have used the following instead:
Dim _registrants As List(Of reg_info) = db.reg_info.OrderBy(Function(t) t.reg_date).ToList
then it will already be ordered.. So the orderby is not needed in the For Each reg In _Registrants.