Asp.net 多对一关系,不需要的连接

Asp.net 多对一关系,不需要的连接,asp.net,asp.net-mvc,entity-framework,entity-framework-6,Asp.net,Asp.net Mvc,Entity Framework,Entity Framework 6,我在模型中定义了多对一关系: Project.CreatedBy=ApplicationUser.Id: class Project{ [Required] public ApplicationUser CreatedBy {get; set;} } 使用映射: modelBuilder.Entity<Project>().HasOptional(i => i.CreatedBy).WithOptionalDependent().WillCascadeOnDelete(fal

我在模型中定义了多对一关系: Project.CreatedBy=ApplicationUser.Id:

class Project{
[Required]
public ApplicationUser CreatedBy {get; set;}
}
使用映射:

modelBuilder.Entity<Project>().HasOptional(i => i.CreatedBy).WithOptionalDependent().WillCascadeOnDelete(false);
生成的SQL看起来像:

SELECT 
[...]
FROM     [dbo].[AspNetUsers] AS [Extent1]
LEFT OUTER JOIN [dbo].[Projects] AS [Extent4] ON ([Extent4].[CreatedBy_Id] IS NOT NULL) AND ([Extent1].[Id] = [Extent4].[CreatedBy_Id])
因此,当某个用户创建了10个项目时,用户实体将乘以10倍。这使我无法通过用户名查找该用户:

context.Users.Single(u => u.Username == "test")
因为它会给我序列包含多个元素异常

你知道如何避免额外的加入吗

我怀疑这与modelBuilder声明有关。我一直在谷歌上搜索这个问题,但从未找到任何解决方案

任何关于modelBuilder和定义与它的关系的资料都将非常感谢。

使用

.FirstOrDefault()
而不是单身

如果找不到对象,此方法将返回第一个对象或null。如果选择了多个元素,则单个方法将引发异常

你也可以使用

.First()
但如果找不到元素,此方法将引发异常

PS我不确定这是否是打字错误,但你必须使用双等号,比如:

context.Users.Single(u => u.Username == "test")
请记住,在这些情况下,通常会创建LoweredUsername列并用于比较:

context.Users.Single(u => u.LoweredUsername == providedUsername.ToLower())
原因如下:

有人可以打约翰而不是约翰 在这种情况下,SQL server端的索引工作正常
我想你有

public virtual ICollection<Project> Projects { get; set; }
请参阅MSDN

或者使项目属性非虚拟

映射

modelBuilder.Entity<Project>()
            .HasOptional(i => i.CreatedBy)
            .WithOptionalDependent()
…将其表示为1:1关联,而不是您希望的1:n关联

因此,将映射更改为一对多:

modelBuilder.Entity<Project>()
            .HasOptional(p => p.CreatedBy)
            .WithMany()
            .HasForeignKey(p => p.CreatedBy_Id);

我不确定在查询用户时为什么EF会加入项目,因为关联是可选的,但正确的1:n映射将停止此操作。

不幸的是,这并不能解决主要问题-不需要的连接。当我想检索ApplicationUser实体时,我认为没有理由加入所有相关的实体,但感谢您指出LoweredUsername。谢谢,它看起来正在工作。我假设WithMany指的是用户创建的许多项目,对吗?你能推荐一些关于modelBuilder的资料吗?是的。如果ApplicationUser有一个属性Projects,它应该是manyu=>u.Projects。
modelBuilder.Entity<Project>()
            .HasOptional(p => p.CreatedBy)
            .WithMany()
            .HasForeignKey(p => p.CreatedBy_Id);