您如何使用 Entity Framework 访问与模型相关的属性?
How do you access a models related properties using Entity Framework?
我正在开发一个简单的应用程序,允许用户创建个人资料并上传多张图片。我正在使用 ASP.NET 标识,因此将 "user" 称为 ApplicationUser
。我有一个 Image
和一个 ApplicationUser
域模型,如下所示:
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; }
}
和
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; }
}
我添加了public virtual ICollection<Image> Image { get; set; }
和public virtual ApplicationUser ApplicationUser { get; set; }
来定义ApplicationUser
和Image
之间的一对多关系。在 运行 应用程序之后,我注意到 Entity Framework 在图像 table 中创建了 ApplicationUser_id
(我假设我可以将其用作外键而不必取消注释中的代码Image
域模型)。
我也有 ViewImagesViewModel
它将 return 到一个视图,我希望能够按 ApplicationUser
的名字、姓氏和城市过滤和排序。我的问题是我不知道如何将两个域模型的属性组合到一个视图模型中。
问题
- 如何在 returning
Image
时访问 return ApplicationUser
的属性?
- 如何将
Image
的相关属性(例如 ApplicationUser
的 UserFirstName
绑定到 ViewImagesViewModel
?
要将所需数据 'eagerly loaded' 放入一个模型中,您可以使用 Include
抓取图片时,还可以抓取用户:
var image = context.Images.Include(i => i.ApplicationUser).FirstOrDefault(i => i.ImageId == imageId);
反之,当获取用户时,您可以获取该用户的所有图像:
var user = context.ApplicationUser.Include(u => u.Image).FirstOrDefault(u => u.Id == userId);
之后,您可以访问image.ApplicationUser.UserSurname
。参见 this MSDN article
正如你所说,你有一个 ViewImagesViewModel
,
所以我认为这个视图模型应该是这样的
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; }
}
以下是如何将域实体映射到视图模型,在控制器操作中这样做
...
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);
}
...
我正在开发一个简单的应用程序,允许用户创建个人资料并上传多张图片。我正在使用 ASP.NET 标识,因此将 "user" 称为 ApplicationUser
。我有一个 Image
和一个 ApplicationUser
域模型,如下所示:
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; }
}
和
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; }
}
我添加了public virtual ICollection<Image> Image { get; set; }
和public virtual ApplicationUser ApplicationUser { get; set; }
来定义ApplicationUser
和Image
之间的一对多关系。在 运行 应用程序之后,我注意到 Entity Framework 在图像 table 中创建了 ApplicationUser_id
(我假设我可以将其用作外键而不必取消注释中的代码Image
域模型)。
我也有 ViewImagesViewModel
它将 return 到一个视图,我希望能够按 ApplicationUser
的名字、姓氏和城市过滤和排序。我的问题是我不知道如何将两个域模型的属性组合到一个视图模型中。
问题
- 如何在 returning
Image
时访问 returnApplicationUser
的属性? - 如何将
Image
的相关属性(例如ApplicationUser
的UserFirstName
绑定到ViewImagesViewModel
?
要将所需数据 'eagerly loaded' 放入一个模型中,您可以使用 Include
抓取图片时,还可以抓取用户:
var image = context.Images.Include(i => i.ApplicationUser).FirstOrDefault(i => i.ImageId == imageId);
反之,当获取用户时,您可以获取该用户的所有图像:
var user = context.ApplicationUser.Include(u => u.Image).FirstOrDefault(u => u.Id == userId);
之后,您可以访问image.ApplicationUser.UserSurname
。参见 this MSDN article
正如你所说,你有一个 ViewImagesViewModel
,
所以我认为这个视图模型应该是这样的
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; }
}
以下是如何将域实体映射到视图模型,在控制器操作中这样做
...
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);
}
...