Getting a foreign key in a table - c#

In my website, a user can add foreignExpressions to his account. The user model looks like this:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public List<ForeignExpression> learnedexpressions { get; set; }
}
Then in the controller I'd like to get the current user's stored expressions like this:
db.ForeignExpressions.Select(f => f.UserId == Membership.GetUser().ProviderUserKey);
However, ForeignExpression does not contain a UserId field, so there's no visible UserId for f. But the UserProfile has a collecion of ForeignExpressions, so I have a UserId field in the ForeignExpression table. I'm confused, how am I supposed to get the ForeignExpressions for my user?
Edit:
public class ForeignExpression
{
public int ID { get; set; }
public string expression { get; set; }
public string context { get; set; }
public string meaning { get; set; }
public DateTime dateAdded { get; set; }
}

int userID = Membership.GetUser().ProviderUserKey;
db.UserProfiles.Find(q => q.UserID == userID).LearnedExpressions.ToList();

Related

How to avoid a relation-property to include its own relation?

public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public string Id { get; set; }
public string Username { get; set; }
public byte[] PasswordHash { get; set; }
public byte[] PasswordSalt { get; set; }
public string Role { get; set; }
public Organization Organization { get; set; }
}
public class Organization
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Phone { get; set; }
public string AccessToken { get; set; }
[ForeignKey("User")]
public string UserId { get; set; }
public User User { get; set; }
}
I have the following two tables created with EF code first.
I need to retrieve my User with Org but I don't want Org property to then again include the same User. How can I avoid that, so all I get is the user with the org?
This is the line that's causing me trouble:
return await _context.Users.Include(x => x.Organization).FirstOrDefaultAsync(x => x.Id == id);
I need to retrieve my User with Org but I don't want Org property to then again include the same User.
Either remove the Organization.User navigation property or, if you just want to remove it from a serialized output, decorate the navigation property with JsonIgnore (or similar)

Unable to create a constant value of type x, only primitive types or enumeration types are supported in this context

I'm trying to convert a SQL statement into LINQ.
I have these models:
public class GamesNight
{
public int id { get; set; }
[DisplayName("Games Night Official Name")]
public string EventName { get; set; }
[DisplayName("Description")]
public string EventDescription { get; set; }
[DisplayName("Date and Time")]
[DataType(DataType.Date)]
public DateTime DateTime { get; set; }
public virtual ApplicationUser User { get; set; }
public bool Active { get; set; }
}
and a GamesNightAttendance, this is more or less linking a user to a games night event.
public class GamesNightAttendance
{
[Key]
public int id { get; set; }
public virtual GamesNight GameNight { get; set; }
public virtual ApplicationUser UserName { get; set; }
public bool Attendance { get; set; }
}
so a user hosts a GamesNight then other users will be able to attend the games night via the gamesnightattendancemodel.
The query I have is:
var userID = User.Identity.GetUserId();
var user = db.Users.First(x => x.Id == userID);
var result = from GNS in db.GamesNights
join GNA in db.GamesNightAttendance on GNS.id equals GNA.id
where GNS.Active & GNA.UserName == user
select new UpcomingGNAttendanceViewModel { GamesNight = GNS, Attendance = GNA.Attendance};
I get the exception:
Message = "Unable to create a constant value of type 'GNR.Models.ApplicationUser'. Only primitive types or enumeration types are supported in this context."
Your naming conventions don't help you:
public virtual ApplicationUser UserName { get; set; }
That's not a username, that's a user. That table is also missing a property to actually hold the relationship, as well as the property to hold the GameNight Id. The Attendance property also doesn't make a lot of sense, as there is no reason for you to create a GamesNightAttendance with Attendance = false.
That class should look more like this:
public class GamesNightAttendance
{
public int Id { get; set; }
// add missing foreign key
public int GameNightId { get; set; }
// add missing foreign key
public int UserId { get; set; }
public virtual GamesNight GameNight { get; set; }
// fix name
public virtual ApplicationUser User { get; set; }
}
With that model, you can now do this:
var userId = User.Identity.GetUserId();
var result =
from gameNight in db.GamesNights
join attendance in db.GamesNightAttendance on gameNight.Id equals attendance.Id
where gameNight.Active && attendance.UserId == userId
select new UpcomingGNAttendanceViewModel
{
GamesNight = gameNight,
Attendance = attendance
};

ASP MVC Application User Null using User.Identity.GetUserId

Ok so I have a relationship between the ApplicationUser and QuestionResults, my models are as below, the userId nor the UserName is retrieved, but I really need the UserId setup as a foreignKey on the QuestionResults entity.
Any help is much appreciated the error that I am receiving is as below:
An exception of type 'System.NullReferenceException' occurred in STRA.dll but was not handled in user code
Additional information: Object reference not set to an instance of an object.
on these lines of code:
qr.User.Id = User.Identity.GetUserId();
qr.User.UserName = User.Identity.GetUserName();
Models
public class QuestionResult
{
public QuestionResult()
{
DateCreated = DateTime.Now;
DateModified = DateTime.Now;
}
public int Id { get; set; }
public DateTime? DateCreated { get; set; }
public DateTime? DateModified { get; set; }
public int QuestionScore { get; set; }
//navigation properties
public virtual ApplicationUser User { get; set; }
//public ICollection<CategoryResult> CategoryResult { get; set; }
//public virtual Category Category { get; set; }
[NotMapped]
public int CategoryId { get; set; }
public virtual Question Question { get; set; }
public int QuestionId { get; set; }
//public virtual Category Category { get; set; }
//public int CategoryId { get; set; }
}
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string Surname { get; set; }
public string Industry { get; set; }
public string GlobalRegion { get; set; }
public string CurrentSituation { get; set; }
public int SalesForceSize { get; set; }
public bool IsVerified { get; set; }
//navigation properties
public virtual ICollection<CategoryResult> CategoryResult { get; set; }
public virtual ICollection<QuestionResult> QuestionResult { get; set; }
//public virtual ICollection<Report> Report { get; set; }
//public virtual ICollection<SurveyResult> SurveyResult { get; set; }
public virtual Organisation Organisation { get; set; }
public int? OrganisationId { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// Add custom user claims here
return userIdentity;
}
}
Your code is equivalent to this::
var user = qr.User;
user.Id = User.Identity.GetUserId();
If the QuestionResult was already linked to a User then you would not be changing which User is linked to the QuestionResult, you would be changing the Id of an existing User - and that is not allowed anyway.
But the QuestionResult is not already linked to a User. qr.User is null - so you get a null reference exception.
In general, life is much easier in Entity Framework if you add the foreign key to your model:
public class QuestionResult
{
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
}
And now you can set the foreign key directly:
qr.UserId = User.Identity.GetUserId();
References:
Why does Entity Framework Reinsert Existing Objects into My Database?
Making Do with Absent Foreign Keys
So, do you wanna make foreing key for userid?
You can do like that:
public int UserRefID { get; set; }
[ForeignKey("UserRefID")]
public xxx UserID { get; set; } //data name like ApplicationUser
And this error appear coz you have some problem about models or data classes.
Set it as a string
Model:
public ApplicationUser User { get; set; }
public string UserId { get; set; }
Controller:
qr.UserId = User.Identity.GetUserId();
And worked perfectly, even created foreign keys, that easy. Thanks so much!

ORM Code first - fix during design

I run into a little trouble understanding object relational mapping in MVC4 simple web application in which there are users and their posted comments.
One user must have a lot of comments. So I added in my UsersContext class public DbSet<UserWork> UserComments { get; set; }
public class UsersContext : DbContext
{
public UsersContext()
: base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<UserWork> UserComments { get; set; }
}
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int? UserComId { get; set; }
[ForeignKey("UserComId")]
public virtual UserComment UserComLog { get; set; }
}
public class UserComment
{
[Key]
public int UserComId{ get; set; }
public int UserId { get; set; }
public string Comments{ get; set; }
public DateTime postDate{get;set}
}
I am now stuck at realizing how all comments posted daily are stored such that I later can make a query like e.g SELECT * FROM UserComment Inner join UserProfile ON UserComment.UserId=UserProfile.UserId WHERE postDate BETWEEN (...) AND (...)
I'm assuming you're using Code First Migrations.
Seems like you need to edit your UserProfile class a little bit to allow for a user to have multiple comments. You need to make UserComLog a collection. Like:
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<UserComment> UserComLog { get; set; }
}
With that, you'll have a user with multiple comments. Then, with the UsersContext you can access the database tables that Entity Framework have created for you. You just need to use your data context to write a Linq statement to access the data.
var context = new UsersContext();
var comments = context.UserComments.Where(d => d.postDate > new DateTime(2013,3,12) && d.postDate < new DateTime(2013,2,12) && d.UserId == userId);
comments would be a IQueryable<UserComment> which you can then pass into a loop to display on a page, or filter further if you wish.

Additional fields MVC

I have table UserProfile, where I have some additional fields, as email, typeAccount, isActivated etc.
When I get Membership.GetUser().(..), I don't have these fields. How to resolve it? And how to change value of this fields?
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public int typeAccount { get; set; }
public bool activated { get; set; }
public string activationcode { get; set; }
public bool del { get; set; }
}
Regards
The membership provider is not handling profiles. If you want to retrieve the UserProfile record of the currently authenticated user simply use the context:
[Authorize]
public ActionResult SomeAction()
{
using (UsersContext db = new UsersContext())
{
UserProfile user = db
.UserProfiles
.FirstOrDefault(u => u.UserName == User.Identity.Name);
// do something with the profile
}
...
}

Categories