最初,我有一个基本的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; }
}
我已将“AccountManager”添加到INCLUDE_STRING
的{{1}},甚至最近尝试使用各种Get
/ ForeignKey
数据注释但无法获取随身携带AccountManager Required
。
有了这个,我认为它是其中的一部分,如果不是我完全不再提出任何User
的全部原因。
简而言之,我对EF关系处理的掌握有限,而且今天我的谷歌搜索能力似乎还没有达到标准。
许多User
到User
。每个Client
一个User
为AccountManager
。为什么这对我这么难?
编辑:圆形答案。
在模型构建器部件中添加:
Client
并修改了modelBuilder.Entity<User>()
.HasRequired(x => x.Client)
.WithMany(x => x.Users);
modelBuilder.Entity<Client>()
.HasOptional(x => x.AccountManager);
以包含用户列表:
Client
这让EF非常高兴能够把它全部搞定。
答案 0 :(得分:1)
问题可能是Code-First约定没有做你真正想要的正确的事情。添加AccountManager
属性后,实体框架约定正在检测一对两个引用导航属性,即User.Client
和Client.AccountManager
。 EF假定它们是同一单一关系的导航端,然后必须是一对一的关系,因为属性是引用而不是集合。
但是你说你真的想要:“许多用户到客户端。一个用户作为每个客户的AccountManager”。这些是两个关系而不仅仅是一个,即两个引用中的每一个属于另一个关系。要实现此目的,您必须使用Fluent API显式覆盖约定:
modelBuilder.Entity<User>()
.HasRequired(u => u.Client)
.WithMany();
modelBuilder.Entity<Client>()
.HasOptional(c => c.AccountManager)
.WithMany();
答案 1 :(得分:0)
这可能有资格作为评论的更多内容,但不适合那里......
Include
的更好方式(IMO)是使用强类型版本:query.Include(u => u.Client)
。使您的代码不易出现运行时错误。 编辑 - This link可以帮助您建立关系。我也注意到您的User
实体缺少ClientId
属性(并且Client
缺少AccountManagerId
)。为了提取“导航属性”(您可能希望包含在Google搜索中的术语,如果您还没有),则需要知道要加入的外键属性。