问题
I'm developing a simple application that will allow users to create a profile and upload multiple images. I'm using ASP.NET Identity and will therefore refer to "user" as ApplicationUser. I have an Image and an ApplicationUser domain model shown below:
public class ApplicationUser : IdentityUser
{
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;
}
public string UserFirstName { get; set; }
public string UserSurname { get; set; }
public string City { get; set; }
public virtual ICollection<Image> Image { get; set; }
}
And
public class Image
{
public int ImageID { get; set; }
public string ImageCaption { get; set; }
public int NumOfLikes { get; set; }
public string ImageFilePath { get; set; }
//[ForeignKey("ApplicationUser")]
//public int ApplicationUserID { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
I added public virtual ICollection<Image> Image { get; set; } and public virtual ApplicationUser ApplicationUser { get; set; } to define a one-to-many relationship between ApplicationUser and Image. After running the application I noticed that Entity Framework had created ApplicationUser_id in the Images table (Which I assume I can use as a foreign key without having to uncomment the code in the Image domain model).
I also have ViewImagesViewModel which will return to a view, a collection of images which I would like to be able to filter and sort by ApplicationUser's name,surname and city. My problem is that I don't know how to combine the properties from both domain models into a single view model.
Questions
- How do I access or return
ApplicationUser's properties when returningImage? - How do I bind
Image's related attributes such asApplicationUser'sUserFirstNametoViewImagesViewModel?
回答1:
To get the required data 'eagerly loaded' into one model, you can use Include
When fetching an image, you can also fetch the user:
var image = context.Images.Include(i => i.ApplicationUser).FirstOrDefault(i => i.ImageId == imageId);
or the reverse, when fetching a user you can fetch all images for that user:
var user = context.ApplicationUser.Include(u => u.Image).FirstOrDefault(u => u.Id == userId);
After that, you can access image.ApplicationUser.UserSurname. See this MSDN article
回答2:
as you said you have a ViewImagesViewModel,
so I thought that this viewmodel should be something like that
public class ViewImagesViewModel
{
public void ViewImagesViewModel()
{
this.Images = new List<ViewImageViewModel>();
}
public string UserFirstName { get; set; }
public string UserSurname { get; set; }
public string City { get; set; }
public List<ViewImageViewModel> Images { get; set; }
}
public class ViewImageViewModel
{
public string ImageUrl { get; set; }
public int Likes { get; set; }
public string Caption { get; set; }
}
and below is how you could map the domain entities to your viewmodel, in the controller action do it like that
...
var entity = db.ApplicationUsers.FirstOrDefault(x => x.Id == 1);
if (entity != null)
{
var model = new ViewImagesViewModel();
model.UserFirstName = entity.UserFirstName;
model.UserSurname = entity.UserSurname;
model.City = entity.City;
// fix the Image property in the ApplicationUser entity to be Images instead of Image as it represent a collection
foreach (var img in entity.Images)
{
var imgModel = new ViewImageViewModel()
{
// you may change this to get the correct Url
ImageUrl = string.Concat(HttpContext.Request.Url.Scheme,
"://", HttpContext.Request.Url.Host,
HostingEnvironment.ApplicationVirtualPath,
img.ImageFilePath),
Likes = img.NumOfLikes,
Caption = img.Caption
};
model.Images.Add(imgModel);
}
return View(model);
}
...
来源:https://stackoverflow.com/questions/33103210/how-do-you-access-a-models-related-properties-using-entity-framework