【问题标题】:Entity Framework include property实体框架包含属性
【发布时间】:2013-09-06 12:28:41
【问题描述】:

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

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

我的Users,以及通常的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; }
}

我已将“AccountManager”添加到 INCLUDE_STRINGGets 中,甚至最近尝试使用各种 ForeignKey/Required 数据注释,但无法将其拉出 AccountManager User和它一起。

因此,我认为这是我无法再提取任何Users 的部分原因,如果不是全部原因的话。

简而言之,我对 EF 关系处理的掌握有些有限,而且我今天的谷歌搜索能力似乎还达不到标准。

许多Users 到Client。每个Client 一个User 作为AccountManager。为什么这对我来说这么难?

编辑:四舍五入的答案。

在模型构建器部分中添加:

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

modelBuilder.Entity<Client>()
            .HasOptional(x => x.AccountManager);

并更改 Client 以包含用户列表:

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; }
}

这让 EF 很高兴能够正确地把它全部拿出来。

【问题讨论】:

  • 您在下面的评论中说“这不是使用 Code First”。您是如何将“AccountManager 的附加属性”添加到课程中的?在视觉设计师表面?还是在 EDMX 文件中?
  • @Slauma 啊,抱歉,显然我撒谎了,我们确实首先使用代码,我在考虑我们不使用的代码首先 migration(不适用于这个项目无论如何)

标签: c# linq entity-framework include linq-to-entities


【解决方案1】:

问题很可能是 Code-First 约定没有做您真正想要的正确事情。添加AccountManager 属性后,实体框架约定检测一对两个参考导航属性,即User.ClientClient.AccountManager。 EF 假定它们是同一个关系的导航端,因此必须是一对一关系,因为属性是引用而不是集合。

但是您说您实际上想要:“一个客户的多个用户。每个客户的一个用户作为 AccountManager”。这些是 两个 关系,而不仅仅是一个,即两个引用中的每一个都属于另一个关系。要实现这一点,您必须使用 Fluent API 显式覆盖约定:

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

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

【讨论】:

  • 这非常接近答案。在模型构建器部分中添加以及向客户端添加 List 属性 - 似乎 EF 对两个表之间的半圆形关系不太满意,并且附加属性帮助设置它。
【解决方案2】:

这可能更像是一个评论,但太多了,不适合那里......

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

编辑 - This link 可以帮助您建立关系。我还注意到您的User 实体缺少ClientId 属性(并且Client 缺少AccountManagerId)。为了提取“导航属性”(如果您还没有的话,您可能希望在 Google 搜索中包含一个术语),它需要知道要加入哪个外键属性。

【讨论】:

  • 编辑了我的问题,添加了完整的获取代码。这不是使用 Code First。
  • 切换到对用户使用完整的 query.Include(x => x.Client) 或对客户使用 query.Include(x => x.AccountManager) 似乎没有太大的影响。用户缺少他们的客户,客户缺少他们的 AccountManagers(但至少我有对象,我猜)
  • @Krenom:更新了答案,提供了更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多