您如何使用 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; }来定义ApplicationUserImage之间的一对多关系。在 运行 应用程序之后,我注意到 Entity Framework 在图像 table 中创建了 ApplicationUser_id (我假设我可以将其用作外键而不必取消注释中的代码Image 域模型)。

我也有 ViewImagesViewModel 它将 return 到一个视图,我希望能够按 ApplicationUser 的名字、姓氏和城市过滤和排序。我的问题是我不知道如何将两个域模型的属性组合到一个视图模型中。


问题

  1. 如何在 returning Image 时访问 return ApplicationUser 的属性?
  2. 如何将 Image 的相关属性(例如 ApplicationUserUserFirstName 绑定到 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);
}
...