实体框架包含属性

本文关键字:属性 包含 框架 实体 | 更新日期: 2023-09-27 18:29:56

最初,我有一个基本的Client,它只包括:

public class Client : Entity
{
    [Required]
    public string Name { get; set; }
}

我的User和通常的Name字段等都有一个Client:

public class User : Entity
{
    [Required, MinLength(4), Display(Name = "Username")]
    public string Username { get; set; }
    [Required, MinLength(2), Display(Name = "First Name")]
    public string FirstName { get; set; }
    [Required, MinLength(2), Display(Name = "Last Name")]
    public string LastName { get; set; }
    [Required, EmailAddress]
    public string Email { get; set; }
    ...
    [Required]
    public virtual Client Client { get; set; }
}

我的Get方法:

public virtual IEnumerable<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        string[] includeProperties = null)
    {
        IQueryable<TEntity> query = dbSet;
        if (includeProperties != null)
            query = includeProperties.Aggregate(query, (q, s) => q.Include(s));
        query = query.Where(x => !x.Deleted);
        if (filter != null)
            query = query.Where(filter);
        return orderBy != null ? orderBy(query).ToList() : query.ToList();
    }

一切都很好。所以,问题是:实际上是我的客户,因为为AccountManager(即User)添加了一个额外的属性,所以它不喜欢我。

public class Client : Entity
{
    [Required]
    public string Name { get; set; }
    [Required]
    public CompanyType CompanyType { get; set; }
    [Required]
    public ClientStatus Status { get; set; }
    [SomethingInHere?]
    public virtual User AccountManager { get; set; }
    public DateTime? AccessFrom { get; set; }
    public DateTime? AccessTo { get; set; }
    public DateTime? ClosedDate { get; set; }
}

我在GetINCLUDE_STRING中添加了"AccountManager",最近甚至尝试使用各种ForeignKey/Required数据注释,但无法将AccountManager User与之一起拉出。

有了这一点,我想这是我再也不能拿出任何User的部分原因,如果不是全部原因的话。

简言之,我对英孚处理关系的能力有点有限,而且我今天在谷歌上的搜索能力似乎达不到标准。

许多CCD_ 14到一个CCD_。一个CCD_ 16作为每个CCD_ 18的CCD_。为什么这对我来说这么难?

编辑:四舍五入的答案。

添加在建模器部件中:

modelBuilder.Entity<User>()
            .HasRequired(x => x.Client)
            .WithMany(x => x.Users);
modelBuilder.Entity<Client>()
            .HasOptional(x => x.AccountManager);

并将CCD_ 19更改为包括用户列表:

public class Client : Entity
{
    [Required]
    public string Name { get; set; }
    [Required]
    public CompanyType CompanyType { get; set; }
    [Required]
    public ClientStatus Status { get; set; }
    public virtual IList<User> Users { get; set; }
    public virtual User AccountManager { get; set; }
    public DateTime? AccessFrom { get; set; }
    public DateTime? AccessTo { get; set; }
    public DateTime? ClosedDate { get; set; }
}

这让英孚非常高兴,能够把一切都做好。

实体框架包含属性

问题可能是"代码优先"约定没有做正确的事情。添加了AccountManager属性后,实体框架约定将检测一对两个引用导航属性,即User.ClientClient.AccountManager。EF假设它们是同一个关系的导航端,然后必须是一对一的关系,因为属性是引用而不是集合。

但你说你实际上想要:"一个客户有很多用户。每个客户有一个用户作为AccountManager"。这是两个关系,而不仅仅是一个,即两个引用中的每一个都属于另一个关系。为了实现这一点,您必须使用Fluent API:明确地覆盖约定

modelBuilder.Entity<User>()
    .HasRequired(u => u.Client)
    .WithMany();
modelBuilder.Entity<Client>()
    .HasOptional(c => c.AccountManager)
    .WithMany();

这可能更像是一个注释,但太多了。。。

  1. 把所有自定义的东西放在一边,试着直接按预期查询EF。这至少可以排除您自己的代码与实体设置方式之间的任何问题(现在很难说,因为我们看不出这个有限的代码示例可能存在问题)
  2. 使用Include的更好的方法(IMO)是使用强类型版本:query.Include(u => u.Client)。使代码不太容易出现运行时错误
  3. 显示无法带回相关属性的查询,并发布所有相关实体/属性。您是否包含与EF约定匹配的外键Id属性?这是使用EF Code First还是EDMX模型

编辑-此链接可以帮助您建立关系。我还注意到您的User实体缺少ClientId属性(并且Client缺少AccountManagerId)。为了提取"导航属性"(如果你还没有,你可能想在谷歌搜索中包含这个术语),它需要知道要加入的外键属性。

相关文章: