I'm pretty new to MVC and the Entity Framework, but I'm sure this should be straight forward. I've got a class with a boolean "Active" flag. I then have a function that returns the results by date descending. All I want to do is ensure that only active records are returned. Should be simple, but it fails with the following error:
Error 13 Overload resolution failed because no accessible 'Where' can be called with these arguments:
Extension method 'Public Function Where(predicate As System.Func(Of Review, Integer, Boolean)) As System.Collections.Generic.IEnumerable(Of Review)' defined in 'System.Linq.Enumerable': Value of type 'Boolean' cannot be converted to 'System.Func(Of PowellCasting.Models.Review, Integer, Boolean)'.
Extension method 'Public Function Where(predicate As System.Func(Of Review, Boolean)) As System.Collections.Generic.IEnumerable(Of Review)' defined in 'System.Linq.Enumerable': Value of type 'Boolean' cannot be converted to 'System.Func(Of PowellCasting.Models.Review, Boolean)'.
Extension method 'Public Function Where(predicate As System.Linq.Expressions.Expression(Of System.Func(Of Review, Integer, Boolean))) As System.Linq.IQueryable(Of Review)' defined in 'System.Linq.Queryable': Value of type 'Boolean' cannot be converted to 'System.Linq.Expressions.Expression(Of System.Func(Of PowellCasting.Models.Review, Integer, Boolean))'.
Extension method 'Public Function Where(predicate As System.Linq.Expressions.Expression(Of System.Func(Of Review, Boolean))) As System.Linq.IQueryable(Of Review)' defined in 'System.Linq.Queryable': Value of type 'Boolean' cannot be converted to 'System.Linq.Expressions.Expression(Of System.Func(Of PowellCasting.Models.Review, Boolean))'. C:\Web Projects\Powell Casting\PowellCasting\PowellCasting\Models\Review.vb 42 14 PowellCasting
It looks as thought it doesn't like comparing Booleans but they have the same data type. I'm sure this should be simple, but would appreciate some help. Please see my code below.
Public Class Review
Private PowellCastingDB As PowellCastingEntites = New PowellCastingEntites
<ScaffoldColumn(False)>
Public Property ReviewID As Integer
<Required(ErrorMessage:="An review title is required")>
<StringLength(256)>
<DisplayName("Title")>
Public Property Title As String
<DisplayName("Heading")>
Public Property Heading As String
<DisplayName("ReviewText")>
<StringLength(4096)>
Public Property ReviewText As String
<DisplayName("Author")>
<StringLength(256)>
Public Property Author As String
<DisplayName("Publication")>
<StringLength(150)>
Public Property Publication As String
<DisplayName("PublicationDate")>
Public Property PublicationDate As Date
<DisplayName("PublicationLink")>
<StringLength(1000)>
Public Property PublicationLink As String
<DisplayName("Image")>
<StringLength(512)>
Public Property Image As String
<DisplayName("Active")>
Public Property Active As Boolean
Public Property Reviews As List(Of Review)
Public Function GetLatestReviews(ByVal count As Integer) As List(Of Review)
Return PowellCastingDB.Reviews.Where(Active = True).
OrderByDescending(Function(a) a.PublicationDate).
Take(count).
ToList()
End Function
End Class
End Namespace
You need to specify a lambda expression:
Return PowellCastingDB.Reviews.Where(Function(x) x.Active = True).
(rest of query)
Or just:
Return PowellCastingDB.Reviews.Where(Function(x) x.Active).
(rest of query)
Try this:
Return PowellCastingDB.Reviews.Where(Function(review) review.Active = True)
Related
I need to compare the values of two lists of objects in VB.NET in a web application. I can't seem to find any working examples of how to do this.
I have tried the example here: https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.sequenceequal?view=netframework-4.0
Where they implement a custom interface for doing so. But even using the exact code gives me errors.
Here is the code I'm currently trying. It's basically the same thing as Microsoft's example but using my own class:
Public Class ForumWithName
Inherits IEquatable(Of ForumWithName)
Private mForumID As Integer
Public Property ForumID() As Integer
Get
Return mForumID
End Get
Set(value As Integer)
mForumID = value
End Set
End Property
Private mForumName As String
Public Property ForumName As String
Get
Return mForumName
End Get
Set(value As String)
mForumName = value
End Set
End Property
Private mSubscribed As Boolean
Public Property Subscribed As Boolean
Get
Return mSubscribed
End Get
Set(value As Boolean)
mSubscribed = value
End Set
End Property
Public Function Compare(ByVal other As ForumWithName) As Boolean
If other Is Nothing Then Return False
Return Me.ForumID = other.ForumID AndAlso Me.Subscribed = other.Subscribed
End Function
Public Overrides Function Equals(ByVal obj As Object) As Boolean
Return Compare(TryCast(obj, ForumWithName))
End Function
Public Overrides Function GetHashCode() As Integer
Return (ForumID, Subscribed).GetHashCode()
End Function
End Class
This code fails to compile because of a few errors:
"Classes can inherit only from other classes"
"Predefined type 'ValueTuple(Of,) is not defined or imported."
"Visual Basic 10.0 does not support tuples"
"'GetHashCode' is not a member of '(ForumID as Integer, Subscribed as Boolean)'"
Once I get this code to work, my plan is to compare two lists of the "ForumWithName" class above.
For example(assume SubscribedsForum1 and SubscribedForums2 are both Lists(Of ForumWithName)):
If SubscribedForums1.SequenceEqual(SubscribedForums2) Then
Return True
Else
Return False
End If
IEquatable is an Interface, it needs to be Implemented and not inherited. (I am guessing here, but I think it's a Typo in the MSDN page you linked)
Change the class declare from:
Public Class ForumWithName
Inherits IEquatable(Of ForumWithName)
to be
Public Class ForumWithName
Implements IEquatable(Of ForumWithName)
Once you have done that, you will also need to add this function
Public Overloads Function Equals(other As ForumWithName) As Boolean Implements IEquatable(Of ForumWithName).Equals
Return Compare(TryCast(other, ForumWithName))
End Function
To work around the problem of not being able to use Tuples, you should be able to use this:
Public Overrides Function GetHashCode() As Integer
Return (ForumID & Subscribed).GetHashCode()
End Function
EDIT:
On a side note, you may want to include the properties ForumName and Subscribed in the GetHashCode function to check if the objects are truly equal to one another.
I'm using ASP.NET Web API to return a custom class object. The class has several properties, one of which takes an optional parameter. All the properties except the one with the optional parameter are available in the resulting JSON response. If I remove the optional parameter the other property is then available as well. Any way to return the other property with the optional parameter in place? Thanks!
Here is the specific property I'm having trouble with:
Public Class customer
...
Public ReadOnly Property photoSrc(Optional shape As String = Nothing) As String
Get
Dim srcString = "/Images/User.png"
If shape = "square" Then
srcString = "/Images/UserSquare.png"
End If
Return srcString
End Get
End Property
...
End Class
And here is the api controller function I'm using to return json:
Public Function GetCustomer(id As Integer) As Object
Dim customer As customer = New customer(id)
Return customer
End Function
A property with a parameter is called an indexed property, or indexer. By design, Json.Net (which is used by Web API for JSON serialization) does not serialize indexed properties, even if the index parameter is optional. (You can see this for yourself in the source code for the GetSerializableMembers method of the DefaultContractResolver class.)
The simplest workaround is to add a separate non-indexed property to your class which calls the indexer with the parameter value you want it to have when serialized. You can make the property private if you want; if you do, you just need to mark it with a <JsonProperty> attribute to allow the serializer to "see" it. You can also use this attribute to give the alternate property the same name in the JSON as the indexed property it is replacing.
Public Class Customer
...
<JsonProperty("photoSrc")>
Private ReadOnly Property defaultPhotoSrc As String
Get
Return photoSrc()
End Get
End Property
Public ReadOnly Property photoSrc(Optional shape As String = Nothing) As String
Get
Dim srcString = "/Images/User.png"
If shape = "square" Then
srcString = "/Images/UserSquare.png"
End If
Return srcString
End Get
End Property
...
End Class
Fiddle: https://dotnetfiddle.net/ffNs9D
How to write the following code so that it will not return the error object reference not set ....
Below is the code.
Private Quantity As String
Public Property Quantity1() As String
Get
Return Quantity.ToString()
End Get
Set(ByVal value As String)
Quantity = value
End Set
End Property
Instantiate your variables. For example...
Private Quantity As String = ""
On another note, you do not have to add ToString to your strings as they are already Strings, it's a non-needed cast.
First, remove the .ToString() calls from your properties. They are completely redundant since the variables you are returning are already strings.
Second, Strings in .net are reference types. Therefore, when you write something like Private Quantity As String, the Quantity is null (Nothing in vb.net), since it points to no string. If you wrote Private Quantity As String = String.Empty then it will not be null.
May be you needs to initialize your private vars with an initial value, or where are you assigning any value to them?
Private Quantity As String = ""
I need an ASP.Net control on your property you can specify an array type string. That is, in my ASP.Net control would have something like:
DefaultValue("")> Category("Misc"), <Bindable(True),
Public Overridable Property MyProperty () As String ()
Get
Return mMyProperty
End Get
Set (ByVal value As String ())
mMyProperty = value
End Set
End Property
And from the ASP.Net page I need to pass the values, type:
<WC:MyControl MyProperty="1,2,4" runat="server" />
The message error is:
Cannot create an object of type 'System.String[]' from its string representation '1,2,4' for the 'MyProperty' property.
You need to implement a TypeConvertor for this.
These resources could help you with it:
How to: Implement a Type Converter
Passing int list as a parameter to a web user control
Passing int array as parameter in web user control
I have a EDM with a entity "Extensions" - within this object is the property extension. I've wired up all the other columns just fine, but this one refuses to wire up. I'm guessing because the entity and the property share the same name?
Here is my code, the extensions doesn't work, the prefix does work:
Imports System.Web.DynamicData
Imports System.ComponentModel.DataAnnotations
<MetadataType(GetType(ExtensionsMetaData))> _
Partial Public Class Extensions
End Class
Public Class ExtensionsMetaData
Private _phones_extensions As Object
Private _prefix As Object
Private _did_flag As Object
Private _len As Object
Private _sfc_id As Object
Private _name_display As Object
Private _floor As Object
Private _room As Object
Private _phones_departments As Object
Private _phones_buildings As Object
Private _phones_phones As Object
Private _phones_restriction_classes As Object
Private _phones_tens As Object
<DisplayName("Extension")> _
Public Property extensions() As Object
Get
Return _phones_extensions
End Get
Set(ByVal value As Object)
_phones_extensions = value
End Set
End Property
<DisplayName("Prefix")> _
Public Property prefix As Object
Get
Return _prefix
End Get
Set(ByVal value As Object)
_prefix = value
End Set
End Property
End Class
How can I get this code to work? I've looked all through my data model and it looks like the name should be Extensions!
The error I am receiving is: The associated metadata type for type 'phoneDBentities.Extensions' contains the following unknown properties or fields: extensions. Please make sure that the names of these members match the names of the properties on the main type.
This is a limitation of EF's "convention over configuration" feature.
Here's a related question: Entity Framework Mapping Oddity - member names cannot be the same as their enclosing type
The easiest way to fix the problem would be to rename the property to "PhoneExtension."