0

最初,我的基本内容Client包括:

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

User的 s 以及通常的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(即 a 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; }
}

我已经INCLUDE_STRINGGets 添加了“AccountManager”,甚至最近尝试使用各种ForeignKey/数据注释,但无法让它连同Required它一起拉出 AccountManager 。User

有了这个,我认为这是我无法再拔出任何Users 的部分原因,如果不是全部原因的话。

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

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

编辑:四舍五入的答案。

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

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 很高兴能够正确地把它全部拿出来。

4

2 回答 2

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();
于 2013-09-04T09:40:53.427 回答
0

这可能有资格作为更多评论,但太多不适合那里......

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

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

于 2013-09-03T13:22:08.723 回答