关系映射实体框架

时间:2018-10-23 10:12:31

标签: c# entity-framework linq asp.net-core mapping

在该项目中,我正在从事currenyly的工作,我坚持以前从未使用过映射等功能,所以我不认为自己是项目建筑师,但对于这个项目,我必须是建筑师。因为,我在阅读该主题时不太好,因此决定使用代码优先方法。 在我的项目中,有3个表VALIDATION USER和FILE。

基本上, USER表保存用户和密码 FILE表具有用户上传的图像名称,这些图像必须由其他用户验证,这使我进入VALIDATION表。 在验证表中,我具有ID,USERID和FILEID,以记录谁验证了什么。

一个用户可以一次验证同一张图像。

在这里您可以看到我的模型

public class File
{
    public int ID { get; set; }
    public string FILE_NAME { get; set; }
    public string URL { get; set; }
    public bool FINAL_IS_VALID { get; set; }
    public DateTime CREATED_DATE { get; set; }
    public int REQ_COUNT { get; set; }
    public int CUR_COUNT { get; set; }
    public double REQ_PER_CENT { get; set; }
    public double CUR_PER_CENT { get; set; }

    public User USER { get; set; }

    public List<Validation> VALIDATION { get; set; }

    public List<Label> LABEL { get; set; }
}

public class User
{
    public int ID { get; set; }
    public string EMAIL { get; set; }
    public string PASSWORD { get; set; }
    public DateTime CREATED_DATE { get; set; }
    public bool IS_ADMIN { get; set; }

    public List<File> FILE { get; set; }

    public List<Validation> VALIDATION { get; set; }
}

public class Validation
{
    public int ID { get; set; }
    public bool IS_VALID { get; set; }
    public DateTime VALIDATION_DATE { get; set; }

    public User USER { get; set; }

    public File FILE { get; set; }
}

我用这种结构完成了大部分工作。但是,当我尝试获取未经用户验证的文件时,我无法使用linq执行此操作。

DbObjects.FILE.Include(x => x.USER).Include(x => x.VALIDATION).ThenInclude(x=>x.USER).Where(x => x.FINAL_IS_VALID != true).ToList(); 

在这种结构下,我无法访问file.validate.user我应该怎么做? 我的结构正确还是有更好的方法做到这一点?我不确定我是否完全了解映射。谢谢。

1 个答案:

答案 0 :(得分:0)

我不确定您是否想建模。

每个User具有零个或多个Files,每个File恰好属于一个User。一个直接的一对多关系。

此外:Files可以分配为Validated。验证是由一个或多个Users完成的。这样的分配称为Validation。每个Validation恰好代表一个File,并且仅由一个User完成。 UsersFiles可以有几个Validations:多对多关系

对于多对多关系,我们需要一个连接表。通常,在实体框架中,您不必指定连接表。实体框架将检测多对多关系并为您创建连接表。

但是,联结表有一些额外的列,其中包括一个属性,表明分配是否已完成:Validation.IsValidated。这就是为什么必须指定联结表的原因。

  

在实体框架中,表的列由   非虚拟属性。虚拟属性代表关系   在表之间。

我看到您偏离entity framework code-first conventions的几个地方。

  • 首先,您的关系没有被宣布为虚拟。
  • 您还忘记了声明外键。
  • 您将many的属性声明为List,而不是ICollection。您确定File.Validation[4]有意义吗?

改进的类定义,遵守约定

class User
{
    public int Id {get; set;}
    ... // other properties

   // every User has zero or more Files (one-to-many)
   public virtual ICollection<File> Files {get; set;}

   // every user has zero or more Validations
   public virtual ICollection<Validation> Validations {get; set;}
}

class File
{
    public int Id {get; set;}
    ... // other properties

   // every File belongs to exactly one User, using foreign key
   public int UserId {get; set;}
   public User User {get; set;}

   // every File has zero or more Validations (one-to-many)
   public virtual ICollection<Validation> Validations {get; set;}
}

最后是验证中的联结表:

class Validation
{
    public int Id {get; set;}
    public bool IsValidated {get; set;}
    ... // other properties

    // every validation belongs to exactly one File, using foreign key
    public int FileId {get; set;}
    public virtual File File {get; set;}

    // every validation belongs to exactly one User, using foreign key
    public int UserId {get; set;}
    public virtual User User {get; set;}
}

您写道:

  

我尝试获取未经用户验证的文件

int userId = ...
var fileNotValidatedByUser = myDbContext.Validatin     // from all Validations
    .Where(validation => validation.UserId == userId   // keep the ones from the specified user
                      && !validation.Isvalidated)      // that are not validated yet
    .Select(validation => validation.File)             // from each remaining validation
                                                       // get the File.
};

查询所有具有一个或多个尚未验证的验证的文件

var filesNotCompletelyValidated = myDbContext.Files      // from the collection of Files
    .Where(file => file.Validations                      // keep only those files that
           .Where(validation => !validation.IsValidated) // have at least one Validation
           .Any());                                      // that is not Validated yet.

查询所有未经验证的文件

var filesNotCompletelyValidated = myDbContext.Files      // from the collection of Files
    .Where(file => !file.Validations                      // keep only those files that
           .Where(validation => validation.IsValidated)   // that have no Validation
           .Any());                                      // that is Validated.