【问题标题】:Entity Framework : create a class with multiple relationships to another实体框架:创建一个与另一个具有多种关系的类
【发布时间】:2021-03-09 15:00:59
【问题描述】:

考虑以下类:

public class Kid
        {
            
            public int Id { get; set; }
            public string FirstName { get; set; } 
            public string LastName { get; set; }
            public Date Time BirthDate { get; set; }
            public ProfilePhoto CurrentProfilePhoto { get; set; }
            public virtual ICollection<ProfilePhoto> ProfilePhotos { get; set; }
    }
 public class ProfilePhoto
        {
            public int Id { get; set; }
            public byte[] PhotoData { get; set; }
            public DateTime DateTaken { get; set; }
            public DateTime DateUploaded { get; set; }
    
            public int KidID { get; set; }
            public Kid Kid { get; set; }
    }

每个孩子实体都有多张个人资料照片,但它可能有也可能没有一张当前的个人资料照片。 另一方面,每个 ProfilePhoto 都与一个孩子相关,并且该孩子的一张 ProfilePhoto 可以是当前的个人资料照片。 如何在 EntityFramework 6.4 中使用 DataAnnotations 或 FluentAPI(如果可能,我更喜欢使用 DataAnnotations)来表示这些关系。

【问题讨论】:

    标签: c# sql-server entity-framework ef-code-first data-annotations


    【解决方案1】:

    您可以使用三种方法:

    选项 1:将 CurrentProfilePhotoId 属性添加到 Kid,作为 CurrentProfilePhoto 导航属性的 FK。

    [ForeignKey("CurrentProfilePhoto")]
    public int? CurrentProfilePhotoId { get; set; }
    public virtual ProphilePhoto CurrentProfilePhoto { get; set; }
    

    选项 2:将 CurrentProfilePhoto 标记为 [NotMapped] 并从 ProfilePhotos 集合中计算它的客户端:

    [NotMapped]
    public ProphilePhoto CurrentProfilePhoto
    {
        get { return ProfilePhotos.OrderByDescending(x => x.DateTaken).FirstOrDefault(); }
    }
    

    选项 3:从实体中删除 CurrentProfilePhoto,并在需要当前照片时依赖于 ViewModel 的投影。即

    var kid = context.Kids
        .Where(x => x.Id == kidId)
        .Select(x => new KidDetailViewModel
        {
            Id = x.Id,
            Name = x.LastName + ", " + x.FirstName,
            BirthDate = x.BirthDate,
            CurrentProfilePhoto = x.ProfilePhotos
                .OrderByDescending(p => p.DateTaken)
                .FirstOrDefault()
        }).Single();
    

    选项 1 非常简单,但是无法明确强制 CurrentProfilePhotoId 引用的任何照片都是该孩子的照片。它可能会意外地关联到与该 Kid ID 无关的任何其他记录的照片。使用此类引用时,建议您在数据库中设置数据完整性检查作业,以提醒您 CurrentPhotoId 引用的照片是否具有不同的孩子 ID。

    选项 2 确保当前照片始终与该孩子相关联,但是您要么需要记住在加载孩子时始终急切加载整个 ProfilePhotos 集合,否则它将触发该集合的延迟加载以获取该集合当前照片。

    选项 3 是我推荐的习惯投影的方法。这可确保仅引用该孩子的照片,并生成一个查询,该查询仅提取足够的数据以填充您在特定时间所需的数据。在此示例中,只会从 Kid 记录中提取一张照片以及必要的详细信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      相关资源
      最近更新 更多