代码之家  ›  专栏  ›  技术社区  ›  SilverLight

LINQ到实体-内部连接无效

  •  0
  • SilverLight  · 技术社区  · 4 年前

    我有两个相关的表格,如下所示:

    用户:

    public partial class Users
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Users()
        {
    
        }
    
        public int ID { get; set; }
        public int UserType_ID { get; set; }
        public string Email { get; set; }
    
        public virtual UserTypes UserTypes { get; set; }
    }
    

    用户类型:

    public partial class UserTypes
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public UserTypes()
        {
            this.Users = new HashSet<Users>();
        }
    
        public int ID { get; set; }
        public string Name { get; set; }
        public string Title { get; set; }
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Users> Users { get; set; }
    }
    

    对于UserType的访问名,我写了以下linq to entity:

    string[] UserTypes = new string[1];
    
    using (Crypto_Entities entities = new Crypto_Entities())
    {
        int User_ID_Integer = int.Parse(User_ID.Trim());
    
        var user = (from User in entities.Users
                    //join UserType in entities.UserTypes on User.UserType_ID equals UserType.ID
                    where User.ID == User_ID_Integer
                    select User).FirstOrDefault();
        if (user != null)
        {
            UserTypes[0] = user.UserTypes.Name;
        }
    }
    

    我的问题是为什么 user.Name 不符合我的目的,这有什么好处 join 在linq到实体?
    如果我移除 参加 正如我在查询中所做的那样,我仍然可以看到UserType的Name字段 user.UserTypes.Name .

    1 回复  |  直到 4 年前
        1
  •  2
  •   Svyatoslav Danyliv    4 年前

    如果已正确定义导航属性,则无需加入。如果你只是需要 Name ,不检索完整实体。

    string[] UserTypes = new string[1];
    
    using (Crypto_Entities entities = new Crypto_Entities())
    {
        int User_ID_Integer = int.Parse(User_ID.Trim());
    
        var query = 
            from User in entities.Users
            where User.ID == User_ID_Integer
            select User.UserTypes.Name;
    
        var name = query.FirstOrDefault();
        if (name != null)
        {
            UserTypes[0] = name;
        }
    }
    

    如果在查询中使用导航属性,EF会自动生成所有需要的连接。但是如果你只是选择了整个实体而没有定义 Include -EF不会加载相关数据。这是有道理的,因为如果有很多关系,否则您可能会加载几乎整个数据库。

        2
  •  0
  •   Guru Stron    4 年前

    因为您已经在实体中设置了关系,所以不需要手动写入连接 load related data :

    var user = entities.Users
       .Include(u => u.UserTypes)
       .Where(u => u.ID == User_ID_Integer)
       .FirstOrDefault();
    

    至于你的连接是无用的——EF核心将代码翻译成实际的SQL(你可以 check )而且,由于您没有从联接表中选择任何数据,这就像在SQL查询中只从联接结果的一个表中选择字段一样无用。