I have a class mapped to an SQL table and can perform a Linq query ok. I need to access some of the information in Products and modify data such as Price before returning as a JSon object.
The problem is a i cant access any of the information in Products. Could someone please advise how i could achieve this?
Class:
<Table(Name:="dbo.VXPartsData")>
Public Class VXPartsData
<Key()>
Public Property PartNo() As String
Public Property CustPart() As String
Public Property ShortDesc() As String
Public Property Part() As String
Public Property Price() As Decimal?
Public Property DiscCode() As String
Public Property Kit() As Boolean
Public Property VXCODE() As String
End Class
Linq query:
Dim Products = DB.VXPartsData.Where(Function(e) e.PartNo = pair.Key).ToList()
Related
Hi i have 3 model class setup Group
Public Class Group
Public Property Id As Long
Public Property Name As String
Public Property CoverImgUrl As String
Public Overridable ReadOnly Property Profile() As ICollection(Of Profile)
Get
End Get
End Property
End Class
Profile
Public Class Profile
Public Property Id As Long
<Required>
<MaxLength(20)>
<Display(Name:="First Name")>
Public Property FirstName As String
<Required>
<MaxLength(20)>
<Display(Name:="Last Name")>
Public Property LastName As String
Public Overridable ReadOnly Property Group() As ICollection(Of Group)
Get
End Get
End Property
and GroupMembers.
Public Class GroupMembers
Public Sub New()
End Sub
Public Overridable Property Group() As Group
Public Overridable Property GroupId() As String
Public Overridable Property Profile() As Profile
Public Overridable Property ProfileId() As String
End Class
i ran the Update-Database command which updated my database and created a table ProfileGroup like asp.net AspNetUserRole.
With the progress so far how can i assign one group to a profile i created like asp.net uses the UserManager.AddToRole method to assign a user to a role or any global best practice to this. Thanks
It looks like you're just trying to set up a many-to-many relationship between Profile and Group. However, you're going about it all wrong.
First, traditionally, you don't actually define a class for the intermediary table, GroupMembers in this case, unless you need a payload, i.e. additional data on the relationship. In your posted code, there's no payload on the relationship, so you're just making your life more difficult this way. Assuming you wanted to keep things as they are, though, you would need to set up your classes like:
Public Class Group
...
Public Overridable Property Profiles As ICollection(Of GroupMember)
End Class
Public Class Profile
...
Public Overridable Property Groups As ICollection(Of GroupMember)
End Class
Public Class GroupMember
Public Property GroupId As String
Public Overridable Property Group As Group
Public Property ProfileId As String
Public Overridable Property Profile As Profile
End Class
This will then be enough for Entity Framework to discern the relationships and create the appropriate tables with the appropriate foreign keys. However, you would be forced to access the Profile/Group indirectly, i.e. profile.Groups.First().Group. Whereas, with an implicit join table, you could just do profile.Groups.First().
So, in order to have an implicit join table, you would just need the following classes:
Public Class Group
...
Public Overridable Property Profiles As ICollection(Of Profile)
End Class
Public Class Profile
...
Public Overridable Property Groups As ICollection(Of Group)
End Class
Notice that the GroupMember class goes away completely. Entity Framework will still see this as a many-to-many and create a table, most likely named dbo.GroupProfiles. If you're not happy with the table name, you can declare it using fluent configuration:
modelBuilder.Entity(Of Profile)().
HasMany(Function(t) t.Groups).
WithMany(Function(t) t.Profiles).
Map(Sub(m)
m.ToTable("GroupMembers")
End Sub)
<HttpGet()>
Public Function Search(<FromUri()> ByVal name As Name) As HttpResponseMessage
// get params from complex type
// or check for model validation
name.firstName;
name.lastName;
End Function
Public Class Name
<Required()>
Public firstName As String
<Required()>
Public lastName As String
End Class
/api/abc/search?firstName=jack&lastName=daniels
I am trying to send a comlex type as a query parameter but name is always null even though I am using fromUri attribute. What am I missing?
EDIT: I am also using Required() attribute from System.ComponentModel.DataAnnotations .
I found the problem. I was missing the Property keywords on my fields.
Public Class Name
<Required()>
Public firstName As String
<Required()>
Public lastName As String
End Class
So, it worked with the following change.
Public Class Name
<Required()>
Public Property firstName As String
<Required()>
Public Property lastName As String
End Class
The problem solved. I think, without properties, the class does not expose its fields, so I cant read them from uri.
I'm learning asp.net MVC. Using the Code First model, where you create your class, and then use the EF to manage all database interactions.
Is there anyway of only requesting some of the fields from a given table using this method, and only updating those fields?
My whole class is:
Public Class Employee
Public Property ID() As Integer
<DisplayName("Staff Name")>
<Required()>
Public Property StaffName() As String
<DisplayName("Location")>
<Required()>
Public Property Location() As String
<Required()>
<DisplayName("Team Leader")>
Public Property teamleader() As String
Public Property ScoreCardM1() As Integer
Public Property ScoreCardM1Notes() As String
Public Property ScoreCardM2() As Integer
Public Property ScoreCardM2Notes() As String
Public Property ScoreCardM3() As Integer
Public Property ScoreCardM3Notes() As String
Public Property ScoreCardM4() As Integer
Public Property ScoreCardM4Notes() As String
Public Property ScoreCardM5() As Integer
Public Property ScoreCardM5Notes() As String
Public Property ScoreCardM6() As Integer
Public Property ScoreCardM6Notes() As String
Public Property ScoreCardTotal() As Integer
Public Property ScoreCardTotalNotes() As String
Public Property ScoreCardM7() As Integer
Public Property ScoreCardM7Notes() As String
Public Property ScoreCardM8() As Integer
Public Property ScoreCardM8Notes() As String
Public Property ScoreCardM9() As Integer
Public Property ScoreCardM9Notes() As String
Public Property ScoreCardQ3Total() As Integer
Public Property ScoreCardQ3TotalNotes() As String
Public Property ScoreCardM10() As Integer
Public Property ScoreCardM10Notes() As String
Public Property ScoreCardM11() As Integer
Public Property ScoreCardM11Notes() As String
Public Property ScoreCardM12() As Integer
Public Property ScoreCardM12Notes() As String
Public Property ScoreCardQ4Total() As Integer
Public Property ScoreCardQ4TotalNotes() As String
Public Property GeneralNotes() As String
End Class
However, I only want to display and edit one month at a time:
Public Class Employee
Public Property ID() As Integer
<DisplayName("Staff Name")>
<Required()>
Public Property StaffName() As String
Public Property ScoreCardM1() As Integer
Public Property ScoreCardM1Notes() As String
End Class
How do I best achieve this? Do I setup another 12 classes, with just one month contained within each, or is there a best practice way of updating a subset of fields within a database row, without affecting the others?
Thanks for any help,
Mark
further to my comment above.... you can set up your classes as follow:
Employee Class:
Public Class Employee
Public Property EmployeeID() As Integer
<DisplayName("Staff Name")>
<Required()>
Public Property StaffName() As String
<DisplayName("Location")>
<Required()>
Public Property Location() As String
<Required()>
<DisplayName("Team Leader")>
Public Property teamleader() As String
Public virtual Property reports() As ICollection<Of MonthlyRports> // not sure if the syntax is right (haven't worked in VB)
End Class
MonthlyReport Class
Public Class Employee
Public Property MonthlyReportID() As Integer // primary key
Public Property EmployeeID() As Integer // foreign key. who this report belongs to
Public Property Month As String // report for month ...
Public Property ScoreCard() As Integer
Public Property ScoreCardNotes() As String
End Class
I have 2 entities:
[TableName("is_userrole")]
public class UserRole
{
[MapField("id"), PrimaryKey, Identity,
public Guid id;
[NotNull]
public string Name;
}
[TableName("is_users")]
public class User
{
[MapField("id"), PrimaryKey, Identity,
NonUpdatable]
public Guid Id;
[NotNull]
public string Name;
[NotNull]
public string Login;
[NotNull]
public string Password;
public Guid UserRole_Id;
[Association(ThisKey = "UserRole_Id", OtherKey = "Id",
CanBeNull = false)]
public UserRole UserRole;
}
and stored procedure on sql server which gets data from query
[Select u., r. from is_users u
inner join is_userrole r on u.userrole_id = r.id]
if i use linq query like
var query = from u in db.User
select new
{
u.Id,
u.Login,
u.Password,
u.UserRole_Id,
u.UserRole
};
Associations filling, but if I execute procedure only parent object(i.e. user) filled.
How in bltoolkit.net associations with stored procedures made?
Or it can be only manually realised?
Thanks.
Ok so I don't have any experience with this but I quickly looked at the unit-tests and it looks like MapResultSet could help you
the unit test are here -> UnitTests\CS\Mapping\ResultSetTest.cs
AssosiationAttribute is used only for Linq expressions.
Point to know: BLT does NO "hidden" actions, for ex. if you will change your linq code as: db.User.ToList() you'll see that UserProperty is not filled. In your sample filling is done because you have said to done it in select clausue, and Association is used only to build proper 'INNER JOIN' in SQL.
I have a .NET 2010 project. In it, I create a basic user class. Instantiate it and successfully fill it with data. The entire time it is doing this, if I hover over the class, it says it is nothing, even as it fills its properties. Later on, it hoses me in the UI, even though the property has a value it says the class is nothing.
I DO instatiate the class...
Dim oExtendedUser As New ExtendedUser
and here is the classs definition...
Public Class ExtendedUser
Inherits System.Web.Security.MembershipUser
Public Sub New()
_Role = New Role
End Sub
Public Property ExtendedUserID As Int32
Public Property FirstName As String
Public Property LastName As String
Public Property Phone As String
Public Property UserID As Guid
Public Property Role As Role
Public Property UserName() As String
Public Property Password() As String
Public Property SecurityQuestion() As String
Public Property SecurityAnswer() As String
End Class
I changed the class. I added MyBase.New() but the problem persists. On the UI, here is the code that executes when the button is clicked. Director has, as a proprety, ExtendedUSer
Dim oCase As New BE.Case
Dim oDirector As New BE.Director
oDirector = SessionManager.Director 'the values are here
oCase.Investigator.ExtendedUserID = oDirector.ExtendedUser.ExtendedUserID
And here is the Director...
Public Class Director
Public Sub New()
_ExtendedUser = New ExtendedUser
End Sub
Public Property ID As Int32
Public Property ExtendedUser As ExtendedUser
End Class
You got tricked by the ToString Override.
Your object exists but it overrides the ToString Method : MembershipUser.ToString
To validate this behavior, try it with a simple class :
VB.NET
Public Class Test
Public Property TestString As String
Public Overrides Function ToString() As String
Return Me.TestString
End Function
End Class
C#
public class Test
{
public string TestString { get; set; }
public override string ToString()
{
return this.TestString;
}
}
With this code, the Watch will show you an instanciated Test to Nothing, because ToString value will be Nothing. The object exist, but Visual Studio is using the ToString Method to populate the value field, and at this point it is Nothing.
VB.NET
Public Class Test
Public Property TestString As String = ""
Public Overrides Function ToString() As String
Return Me.TestString
End Function
End Class
C#
public class Test
{
public Test()
{
this.TestString = "";
}
public string TestString { get; set; }
public override string ToString()
{
return this.TestString;
}
}
With this code you'll get an empty string.
To get back to your code, you cannot extend the MembershipUser so simply, you have to follow this guideline : How to: Implement a Custom Membership User. As many things won't work with your actual extension (For example, your username shadowing the base one).
See this question as well. There are easier ways to extend your user "entity" than inheritance.