Query with four tables in ASP.net using lambda expression - c#

I have a web page that allows user to sign petitions, in the user detail page I want to display the petitions the user has signed, including the petition image. The image is specific to the category of the petition.
I have a category model that holds the image
public class Category
{
public int CategoryID { get; set; }
public string Name { get; set;}
public string catImage { get; set; }
public ICollection<Cause> Causes { get; set; }
}
Then I have a cause model that links to the Category through CategoryID
public class Cause
{
public int CauseID { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int UserID { get; set; }
public string createdBy { get; set; }
public DateTime createdOn { get; set; }
public int Target { get; set; }
public int CategoryID { get; set; }
public virtual ICollection<Signature> Signatures { get; set; }
public Category Category { get; set; }
}
Then a signature model that links the Cause to the User
public class Signature
{
public int SignatureID { get; set; }
public int CauseID { get; set; }
public int UserID { get; set; }
public DateTime signedOn { get; set; }
public virtual Cause Cause { get; set; }
public virtual User User { get; set; }
}
And finally a user model
public class User
{
public int ID { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string UserImage { get; set; }
public Role Role { get; set; }
public virtual ICollection<Signature> Signatures { get; set; }
}
On the user details page I am trying to display a table with a list of all the petitions the user has signed. I have been able to show the name and the date shown, but not the images.
I would really appreciated any help.
Thanks

Related

Why is it that if I include a navigation property does it include some of the navigation properties of the property that I want to include?

I have a problem and it is that when I load a navigation property of an entity, it loads the other navigation properties of the property that I am loading, which generates me as a loop.
Company.cs
public class Company
{
[Key]
public int Id { get; set; }
public int UserId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string EmailPassword { get; set; }
public int EmailType { get; set; }
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public bool IsActive { get; set; } = true;
public User User { get; set; }
public List<CompanySpecialty> CompanySpecialties { get; } = new List<CompanySpecialty>();
public List<CompanySchedule> CompanySchedules { get; } = new List<CompanySchedule>();
}
CompanySpecialty.cs
public class CompanySpecialty
{
[Key]
public int Id { get; set; }
public int CompanyId { get; set; }
public Company Company { get; set; }
public string Description { get; set; }
public double Cost { get; set; }
public int DurationInMinutes { get; set; }
public bool IsActive { get; set; } = true;
}
I have these entities, the problem occurs when in the entity Company I try to load the property CompanySpecialties since the property company specialties loads the property Company that it owns, and it is property ** Company** reloads the property CompanySpecialties and so on.
What I want is to know how to load only once and not load recursively.
I wait an answer. Thanks.

Finding a table based on foreign key

I have these two tables and the bridge between them:
public class User
{
[Required]
public string Email { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public int Id { get; set; }
public ICollection<UserLocation> UserLocations { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string Username { get; set; }
}
public class Location
{
[Required]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Picture { get; set; }
public string PostCode { get; set; }
public string Region { get; set; }
public ICollection<UserLocation> UserLocations { get; set; }
}
public class UserLocation
{
public Location Location { get; set; }
public int LocationId { get; set; }
public User User { get; set; }
public int UserId { get; set; }
}
I need to create a method that takes as a parameter a search field and a user id, returns all locations realted to that user id and searches if the string is contained in any of the locations' props.
I am having issues returning the locations based on user id.
I tried _context.UserLocations.Include(ul=>ul.Location).Where(l=>l.UserId==userId)
but that didn't work since I got a syntax error when trying to use l.UserId.
I also tried the other way around, _context.Locations.Include(l=>l.UserLocations) but ran into the same issue.
I need to find a way to retrieve all locations related to the user. The search can be easily done using the Contains() method afterwards.
Try this
_context.UserLocations.Where(x => x.UserId == userId).Select(x => x.Location)

Retrieving data from a different connection after logging in?

I am building a holiday tracking website.
I have two data connections in my mvc application.
DeafultConnection which contains aspnetusers which I am using for user logins and Registrations.
Then LotusWorksEntities which I am using to track Employee details such as holiday requests, hours taking etc.
In DefaultConnections under aspnetusers, there's a column for email.
In LotusWorksEntitles under Employee Table, there's also a column for email.
On my Admin view page, I have a list of all Employees which has a column for Site.
I want Admins who have been assigned certain sites to only see employees from those assigned sites.
I have done this manually by
public ActionResult Index()
{
var employees = db.Employees.Include(e => e.Area).Include(e => e.Discipline).Include(e => e.Shift).Include(e => e.Site).Where(e => e.SiteID == 2);
return View(employees.ToList());
}
Is there a way that I could connect these two connections, so that when an admin logs in, it knows what site they've been assigned to and displays those employees under that site.
Here are my models:
public partial class Employee
{
public int EmployeeID { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public System.DateTime StartDate { get; set; }
public int RoleID { get; set; }
public int ShiftID { get; set; }
public int AreaID { get; set; }
public int DisciplineID { get; set; }
public int SiteID { get; set; }
public int ALCategory { get; set; }
public int HoursTaken { get; set; }
public Nullable<int> AwardedLeave { get; set; }
public Nullable<int> TotalHoursThisYear { get; set; }
public int HoursCarriedForward { get; set; }
public Nullable<int> EntitlementRemainingThisYear { get; set; }
public string Comments { get; set; }
public int SickLeaveTaken { get; set; }
public Nullable<int> SickLeaveEntitlement { get; set; }
public Nullable<int> SickLeaveEntitlementRemaining { get; set; }
public int StudyLeaveEntitlement { get; set; }
public int StudyLeaveTaken { get; set; }
public Nullable<int> StudyLeaveRemaining { get; set; }
public int ExamLeaveTaken { get; set; }
public int ForceMajeure { get; set; }
public int BereavementLeaveTaken { get; set; }
public int MaternityLeaveTaken { get; set; }
public int ParentalLeaveTaken { get; set; }
public int AdoptionLeaveTaken { get; set; }
public string ManagerEmail { get; set; }
public string AreaManagerEmail { get; set; }
public virtual Area Area { get; set; }
public virtual Discipline Discipline { get; set; }
public virtual Shift Shift { get; set; }
public virtual Site Site { get; set; }
}
Then my Site Model is:
public partial class Site
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Site()
{
this.Employees = new HashSet<Employee>();
}
public int SiteID { get; set; }
public string SiteName { get; set; }
public string SiteManager { get; set; }
public string SiteDelegate { get; set; }
public string SiteAdmin { get; set; }
public string SiteLocation { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Employee> Employees { get; set; }
}
Employee Table and Site Table are connected through a foreign key.
Not completely understood which two connections you have is it database connection you are talking about?
But anyways you can use Linq joins to connect two separate list of objects in C#. filter data. Basically your two list should have some relation for join to work.
Here it is explained how to join two list in memory.

SQL Exception trying to add an existing user when context.SaveChanges() on a different table

I am trying to add an entry to a table that holds a users browsing history information. However, when trying to save the addition an SqlException is thrown:
Cannot insert duplicate key row in object 'dbo.AspNetUsers' with
unique index 'UserNameIndex'. The duplicate key value is
(exampleUserName). The statement has been terminated.
A user is has many browsing histories but a browsing history can only be attached to one user so there is a user as part of the BrowsingHistory DataModel:
namespace DataModels
{
[Table("BrowsingHistory")]
public class BrowsingHistory
{
[Key]
public int BrowsingHistoryId { get; set; }
public int ProductId { get; set; }
public System.DateTime DateTime { get; set; }
public int DeviceId { get; set; }
public int UserId { get; set; }
public virtual AspNetUsers User { get; set; }
public virtual Device Device { get; set; }
public virtual Product Product { get; set; }
}
}
It is to note that I am using the Microsoft Identity classes for my authentication. The user class looks as follows:
namespace DataModels
{
using System;
using System.Collections.Generic;
[Table("AspNetUsers")]
public class AspNetUsers
{
public AspNetUsers()
{
BrowsingHistories = new HashSet<BrowsingHistory>();
Orders = new HashSet<Order>();
AspNetUserClaims = new HashSet<AspNetUserClaims>();
AspNetRoles = new HashSet<AspNetRoles>();
}
[Key]
public int Id { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
public string PasswordHash { get; set; }
public string SecurityStamp { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public bool TwoFactorEnabled { get; set; }
public DateTime? LockoutEndDateUtc { get; set; }
public bool LockoutEnabled { get; set; }
public int AccessFailedCount { get; set; }
public string UserName { get; set; }
public string HouseName { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string Town { get; set; }
public string County { get; set; }
public string Postcode { get; set; }
public string ContactNumber { get; set; }
public virtual ICollection<BrowsingHistory> BrowsingHistories { get; set; }
public virtual ICollection<Order> Orders { get; set; }
public virtual ShoppingCart ShoppingCart { get; set; }
public virtual ICollection<AspNetUserClaims> AspNetUserClaims { get; set; }
public virtual ICollection<AspNetRoles> AspNetRoles { get; set; }
}
}
The error occurs when trying to save the addition in the repository. On the _context.SaveChanges() line the method below.
public void CreateBrowsingHistoryEntry(BrowsingHistory bhe)
{
_context.BrowsingHistory.Add(bhe);
_context.SaveChanges();
}
Any help with this issue would be greatly appreciated.

C# mongodb model like Facebook

I'm working on a project where the MongoDB model will be similar to Facebook. So we all know how FB works, a user "likes" a band/company page, and that user will see all the posts from that page.
Is the below model how I should design this?
If a Page has million likes, then each Post will have a million sub documents of Like. That does not seem right, there must be a better way that I cant think of.
Thanks.
public class Person
{
public ObjectId Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Page
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<Like> PersonLikes { get; set; }
}
public class Like
{
public ObjectId Id { get; set; }
public ObjectId UserId { get; set; }
public DateTime DateLiked { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public ObjectId PageId { get; set; }
public string Message { get; set; }
public List<Like> PersonLikes { get; set; }
}
My take assuming you only want to track likes
public class Page
{
public ObjectId Id { get; set; }
public DateTimeOffset Date { get; set; }
public string Name { get; set; }
public int NumberOfLikes { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public ObjectId PageId { get; set; }
public DateTimeOffset Date { get; set; }
public string Message { get; set; }
public int NumberOfLikes { get; set; }
}
I would then queue the Reaction (Like or Dislike) for insertion, "sentiment" information doesn't have to be stored in real time, does it? These are not medications, bank transactions, etc.
public class Like
{
public ObjectId Id { get; set; }
public ObjectId ParentId { get; set;}
public ObjectId UserId { get; set; }
public DateTimeOffset Date { get; set; }
}
Queue where? to a collection of Likes. Why not part of the page or post? Because if a post goes viral (as you said even though the majority won't), you may end up with a 1,000,000 likes. Who is going to browse this information other than an analytic engine?
You also have to ensure a user can only express their reaction only once per item.
The post only exists on one page so it´s the page that should own the post, not the post owning the page.
public class Person
{
public ObjectId Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Page
{
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<Like> PersonLikes { get; set; }
public List<Post> Posts { get; set; }
}
public class Post
{
public ObjectId Id { get; set; }
public string Message { get; set; }
public List<Like> Likes { get; set; }
}
public class Like
{
public ObjectId Id { get; set; }
public ObjectId UserId { get; set; }
public DateTime DateLiked { get; set; }
}

Categories