Finding a table based on foreign key - c#

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)

Related

Query with four tables in ASP.net using lambda expression

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

Entity Framework many to many to single object

I am trying to map a property on a user that that has a many to many relationship in the database but there is only ever one per user. But I am unable to figure out the required map in entityframework. I have the following entities:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
//Need to map this property
public virtual SecurityRole SecurityRole { get; set; }
}
public class SecurityRole
{
public int Id { get; set; }
public string Name { get; set; }
}
An the following tables:
User:
Id
FirstName
LastName
SecurityRole:
Id
Name
UserSecurityRole:
UserId
SecurityRoleId
If anyone has any idea or could point me in the right direction that would be great
Even if there is only one record in the database, if you have a many to many relationship between User and SecurityRole it should work like this:
public class User
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<SecurityRole> SecurityRoles { get; set; }
}
public class SecurityRole
{
public int Id { get; set; }
public string Name { get; set; }
public List<User> Users { get; set; }
}

Expanding classes using AutoMap

I have to import a set of data from one database to another with a somewhat different schema, and I'm considering using AutoMap. I could just write a bunch of SQL scripts, but I already have both databases in EF and I want to learn AutoMap ...
While many of the classes are similar, the problem I'm having is where the structure is really different. The target models were designed with several more layers of classes. Instead of flattening, I need to expand.
The target classes have the following properties:
public class Account
{
public int Id { get; set; }
public string Name { get; set; }
public ContactInfo Location { get; set; }
public List<Policy> Policies { get; set; }
}
public class ContactInfo
{
public int Id { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public State State { get; set; }
public string Zip { get; set; }
public string EMail { get; set; }
public List<Phone> PhoneNumbers { get; set; }
}
public class Phone
{
public int Id { get; set; }
public string Name { get; set; }
public string Number { get; set; }
}
public class Policy
{
public int Id { get; set; }
public PolicyNumber PolicyNumber { get; set; }
public List<Transaction> Transactions { get; set; }
}
The source tables, however, are relatively flattened.
public partial class Account
{
public string AccountId { get; set; }
public string AccountName { get; set; }
public string PolicyNumber { get; set; }
}
public partial class Transaction
{
public int TransactionId { get; set; }
public int AccountId { get; set; }
public Nullable<System.DateTime> EffectiveDate { get; set; }
public string InsuredName { get; set; }
public string InsuredAddress { get; set; }
public string InsuredCity { get; set; }
public string InsuredState { get; set; }
public string InsuredZip { get; set; }
public string InsuredPhone { get; set; }
}
I can create the Map, but I don't know how to tell AutoMapper to handle converting the string Policy to a policy object and then add it to the list of Policies.
Mapper.CreateMap<Source.Account, Destination.Account>();
Even worse, the source data inexplicitly has the name and address info at the transaction level. Before you tell me that AutoMap might not be the best solution, please understand that these two source tables are 2 out of over 40 tables in this database, and that the others are not nearly as troublesome.
Can I configure AutoMap to convert the string property PolicyNumber to a Policy Object and add it to the Policies List of the target class?
Any suggestions on how I can get the name and address information from the Transaction into a ContactInfo class and add it at the Account level?
Thank you.
Thanks to Thomas Weller. Custom Value Resolvers handled exactly what I needed.

How can i expose dto objects using wcf data service with ef code first?

I am trying to make a wcf data service where i dont want to get acces to the database models but instead i want to use Data transfer objects. I have been reading a lot on the internet about how to accomplish this but i cant get a good answer for my problem. It is the first time for me doing something with wcf data services so i am a little inexperienced.
Oke here are my models that are linked to my database using Entity Framework
public class User
{
[Key]
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string CountryCode { get; set; }
public string PhoneNumber { get; set; }
public ICollection<User> Contacts { get; set; }
public virtual Language Language { get; set; }
public User()
{
Contacts = new List<User>();
}
}
public class Message
{
[Key]
public int MessageId { get; set; }
public DateTime SentDate { get; set; }
public virtual User Sender { get; set; }
public virtual User Receiver { get; set; }
public string Content { get; set; }
public string OriginalCultureInfoEnglishName { get; set; }
public string ForeignCultureInfoEnglishName { get; set; }
}
public class Language
{
[Key]
public int LanguageId { get; set; }
public string CultureInfoEnglishName { get; set; }
}
Now i made a Service.svc which has my DatabaseContext so it can directly acces my database models. What i want to achieve is that instead of directly getting the database models i would like to get the DTO models when i query against my service.
A Example of how my dto's would look like
public class UserDTO
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Country { get; set; }
public string PhoneNumber { get; set; }
public ICollection<ContactDTO> Contacts { get; set; }
public virtual LanguageDTO Language { get; set; }
public UserModel()
{
Contacts = new List<ContactDTO>();
}
}
public class ContactDTO
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Country { get; set; }
public string PhoneNumber { get; set; }
public virtual LanguageDTO Language { get; set; }
}
public class LanguageDTO
{
public int LanguageId { get; set; }
public string CultureInfoEnglishName { get; set; }
}
public class MessageDTO
{
public int MessageId { get; set; }
public DateTime SentDate { get; set; }
public virtual ContactDTO Sender { get; set; }
public virtual ContactDTO Receiver { get; set; }
public string Content { get; set; }
public string OriginalCultureInfoEnglishName { get; set; }
public string ForeignCultureInfoEnglishName { get; set; }
}
Now is it possible to do it like this by making a different context that i can use in my service.svc or is there any other way to achieve the this?
for example i would like to get ContactDto by userid which is a user but with less properties because they are not relevant in the client application. I see this happening by a uri http://localhost:54895/Service.svc/ContactDto(1)
Hopefully anyone can clear this up for me because it is really frustrating :)
I'm not sure that what you're interested in is possible, exactly. You are looking to have multiple entity sets per type (aka MEST), and I don't know how well that's supported.
Beyond that point, and into a discussion around DTOs in general...
If you use custom providers, you can implement your own IDataServiceMetadataProvider and IDataServiceQueryProvider. When your service starts, you can make calls into the IDataServiceMetadataProvider to control what entities and properties are exposed or hidden -- including exposing properties that do not actually exist on your entity. The upshot is that you end up with a DTO without coding a DTO class. The exposed metadata is the DTO. This is a good resource for creating your own providers.
In your case, this isn't a 100% solution, because you can't selectively choose when a property is exposed and when it's not.
Hope this helps...

Entity Framework Query based on child object filter and at the same time on the main object

I have a class called Query with a field called CreatedBy, the username who created it.
I also have a class called Permissions with the permissions for the query.
I created a query that returns me based on the current user, the queries the user has access to, based on the Permissions collection, but I need to JOIN that with the queries that the user also created.
If for some reason, the user who created it, its also in the Permissions collection, it shouldnt be returned twice.
Here is my code
public class Query
{
public int QueryId { get; set; }
public string QueryName { get; set; }
public string QuerySql { get; set; }
public string CreatedBy { get; set; }
public string QueryType { get; set; }
public string RequestType { get; set; }
public string Column1 { get; set; }
public string Operator1 { get; set; }
public string Value1 { get; set; }
public string Connector2 { get; set; }
public string Column2 { get; set; }
public string Operator2 { get; set; }
public string Value2 { get; set; }
public string Connector3 { get; set; }
public string Column3 { get; set; }
public string Operator3 { get; set; }
public string Value3 { get; set; }
public virtual ICollection<Permission> Permissions { get; set; }
}
public class Permission
{
public int PermissionId { get; set; }
public string UserName { get; set; }
}
public IQueryable<Query> GetQueriesForUser(string userName)
{
return _context.Queries.Where(q => q.Permissions.Any(p => p.UserName.Equals(userName)));
}
Are you sure you need a join? It looks like you need UNION ALL:
_context.Queries.Where(q => q.Permissions.Any(p => p.UserName == userName)).Concat(
_context.Queries.Where(q => q.CreatedBy == userName));

Categories