EF核心:无效的列名'companyId1'

时间:2019-07-26 11:37:19

标签: c# sql entity-framework-core

我很难理解为什么EF生成的SELECT子句包含两次主键,第二个后缀为'1'。

exec sp_executesql N'SELECT [entity.WebAdminCompanyUser].[CompanyId], [entity.WebAdminCompanyUser].[AspNetUserId], [entity.WebAdminCompanyUser].[CompanyId1]
FROM [SafeProtect].[WebAdminCompanyUser] AS [entity.WebAdminCompanyUser]
INNER JOIN (
    SELECT [entity1].[AspNetUserId]
    FROM [SafeProtect].[WebAdminUser] AS [entity1]
    WHERE ([entity1].[RowEnabled] = 1) AND EXISTS (
        SELECT 1
        FROM [SafeProtect].[WebAdminCompanyUser] AS [companyUser1]
        WHERE ([companyUser1].[CompanyId] = @__companyId_0) AND ([entity1].[AspNetUserId] = [companyUser1].[AspNetUserId]))
) AS [t0] ON [entity.WebAdminCompanyUser].[AspNetUserId] = [t0].[AspNetUserId]
ORDER BY [t0].[AspNetUserId]',N'@__companyId_0 int',@__companyId_0=1

失败,并显示无效的列名'CompanyId1'

以下是实体和相应的配置(流利的API):

WebAdminCompanyUser

public partial class WebAdminCompanyUser : ITrackable, IMergeable
{
    public WebAdminCompanyUser()
    {
        AdditionalInit();
    }

    public int CompanyId { get; set; }
    public int AspNetUserId { get; set; }

    public virtual Company Company { get; set; }

    [NotMapped]
    public TrackingState TrackingState { get; set; }

    [NotMapped]
    public ICollection<string> ModifiedProperties { get; set; }

    [NotMapped]
    public Guid EntityIdentifier { get; set; }

    partial void AdditionalInit();
}

}

配置:

builder.Entity<WebAdminCompanyUser>(entity =>
{
    entity.ToTable(name: "WebAdminCompanyUser", schema: SqlSchema.SafeProtect);
    entity.HasKey("CompanyId", "AspNetUserId");

    entity
       .HasOne(d => d.Company)
       .WithMany()
       .HasForeignKey(d => d.CompanyId)
       .IsRequired();
});

WebAdminUser

public partial class WebAdminUser : IdentityUser<int>, IAuditInfo, IRowDisableableWithDateTime, ITrackable, IMergeable
{
    public WebAdminUser()
    {
        WebAdminCompanyUser = new HashSet<WebAdminCompanyUser>();
        WebAdminUserRole = new HashSet<WebAdminUserRole>();
        WebAdminUserClaim = new HashSet<WebAdminUserClaim>();
        WebAdminUserLogin = new HashSet<WebAdminUserLogin>();

        AdditionalInit();
    }

    public string DisplayName { get; set; }
    public DateTime CreatedOn { get; set; }
    public DateTime? ModifiedOn { get; set; }
    public bool RowEnabled { get; set; }
    public DateTime? DisabledOn { get; set; }

    public virtual ICollection<WebAdminCompanyUser> WebAdminCompanyUser { get; set; }
    public virtual ICollection<WebAdminUserRole> WebAdminUserRole { get; set; }
    public virtual ICollection<WebAdminUserClaim> WebAdminUserClaim { get; set; }
    public virtual ICollection<WebAdminUserLogin> WebAdminUserLogin { get; set; }

    [NotMapped]
    public TrackingState TrackingState { get; set; }

    [NotMapped]
    public ICollection<string> ModifiedProperties { get; set; }

    [NotMapped]
    public Guid EntityIdentifier { get; set; }

    partial void AdditionalInit();
}

配置:

    builder.Entity<WebAdminUser>(entity =>
    {
        entity.ToTable(name: "WebAdminUser", schema: SqlSchema.SafeProtect);
        entity.Property(e => e.Id).HasColumnName("AspNetUserId");

        // authorize multiple user name
        entity.HasIndex((p) => new { p.UserName }).IsUnique(false);

        entity
              .HasMany(user => user.WebAdminUserClaim)
              .WithOne()
              .HasForeignKey(userClaims => userClaims.UserId)
              .IsRequired();

        entity
            .HasMany(user => user.WebAdminUserLogin)
            .WithOne()
            .HasForeignKey(userLogin => userLogin.UserId)
            .IsRequired();

        entity
            .HasMany(user => user.WebAdminUserRole)
            .WithOne()
            .HasForeignKey(userRole => userRole.UserId)
            .IsRequired();

        entity
             .HasMany(user => user.WebAdminCompanyUser)
             .WithOne()
             .HasForeignKey(companyUser => companyUser.AspNetUserId)
             .IsRequired();
    });

EF查询:

IQueryable<WebAdminUser> query =
                    from WebAdminUser user WebAdminUserRepository.All()
                        .Include(user => user.WebAdminUserRole)
                            .ThenInclude(userRole => userRole.AspNetRole)
                        .Include(user => user.WebAdminCompanyUser)
                    where user.WebAdminCompanyUser.Any(companyUser => companyUser.CompanyId == companyId)
                    select user;

                return query.ToList();

任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

通常,当您通过将某些导航属性保留为不流畅的配置而无法正确映射关系时,就会发生这种情况。

请记住,每个导航属性(集合或引用)都代表一个关系。如果您流畅地配置关系并使用HasOne / HasMany / WithOne / WithMany而不通过导航属性,则您正在告诉EF关系没有导航属性对应的结尾。但是,如果您实际上具有导航属性,则EF会将其映射为具有默认FK列名称的单独关系。如果已经使用默认的属性/列名称,则EF会将索引附加到该属性/列,直到其唯一为止。

对于您来说,您显示的WebAdminUser类和配置是不相关的。无效的列名CompanyId1表示问题与您未显示的Company类有关,此处有WithMany()调用

   .HasOne(d => d.Company)
   .WithMany() // <--

您的Company类很可能具有WebAdminCompanyUser的集合导航属性,如下所示(virtual,该属性的名称无关紧要):

public virtual ICollection<WebAdminCompanyUser> CompanyUsers { get; set; }

然后,您需要使用类似的方法更改上述{​​{1}}调用

.WithMany()

问题将得到解决。