Entity Framework 联接是否应该在父级 table 中包含 table?

Should an Entity Framework join contain the table within the parent table?

我定义了以下实体:

public partial class ImportConnection
{
    public int id { get; set; }
    public int fkCompanyID { get; set; }
    public int fkUserTypeID { get; set; }
    public int fkDataConnection { get; set; }
    public System.DateTime RecordCreated { get; set; }
    public Nullable<System.DateTime> RecordUpdated { get; set; }
    public string ConnectionName { get; set; }
    public bool isEnabled { get; set; }
    public bool isPrimary { get; set; }
    public bool ManageUsersOnImport { get; set; }
    public bool ManageGroupsOnImport { get; set; }
    public bool isValidated { get; set; }
    public bool isErrored { get; set; }
    public int XLoc { get; set; }
    public int YLoc { get; set; }
    public int FrequencyInMinutes { get; set; }
    public Nullable<System.DateTime> ScheduledStartTime { get; set; }
    public Nullable<System.DateTime> ActualStart { get; set; }
    public Nullable<System.DateTime> QueuedTime { get; set; }
    public Nullable<System.DateTime> ActualCompletion { get; set; }
    public int LastRunLengthTime { get; set; }
    public string ImportQuery { get; set; }
    public string IdentityColumn { get; set; }
    public string LastRunMessage { get; set; }

    public virtual Company Company { get; set; }  //<---- here
    public virtual UserType UserType { get; set; } 
    public virtual DataConnector DataConnector { get; set; } //<---- and here
}

我正在使用以下查询从数据库加载 table。我也加入了另外两个 table。如果我在 SQL Server Management Studio 中 运行 这个(必须稍微修改查询)我得到了公司和数据连接器所以我知道数据库中的数据是正确的(键匹配)。

List<ImportConnection> dcList = await (from data in db.ImportConnection
                                       join dc in db.DataConnector on data.fkDataConnection equals dc.id
                                       join co in db.Company on data.fkCompanyID equals co.Id
                                       where data.ScheduledStartTime < DateTime.Now
                                          && data.isEnabled == true
                                          && dc.isValidated == true
                                          && !data.isErrored
                                       select data).ToListAsync();

但是,加载查询后,我从 ImportConnection 获取数据,但 CompanyDataConnector 均为空。

连接中的 table 不应该显示在顶部实体对象中吗?如果是,是什么原因导致数据未显示?

如果您不使用架构使用的命名约定配置 EF,EF 将采用 FK 的约定默认值。设置导航属性后,您无需在 Linq 表达式中添加联接,只需将它们 .Include() 添加到 eager-load,或者让 EF Lazy 按需加载它们。

如果您启用了迁移,您可能会发现您的 table 已按照 EF 的默认约定添加了诸如“CompanyID”之类的列。

要配置您的 FK:

[ForeignKey("Company")]
public int fkCompanyID { get; set; }
[ForeignKey("UserType")]
public int fkUserTypeID { get; set; }
[ForeignKey("DataConnection")]
public int fkDataConnection { get; set; }

然后查询:

List<ImportConnection> dcList = await db.ImportConnection
    .Include(x => x.DataConnector)
    .Include(x => x.UserType)
    .Include(x => x.Company)
    .Where( x => x.ScheduledStartTime < DateTime.Now
        && x.isEnabled
        && x.DataConnector.isValidated
        && !x.isErrored)
    .ToListAsync();

要检查的另一件事是,您的关系是否针对 many-to-one 正确设置,而不是一对一。在 EF6 中,如果关系标记为 one-to-one,则 EF 将在两个 table 上使用 PK 作为相关 FK。

即如果您的 EntityTypeConfiguration / modelBuilder 配置引用:

.HasRequired(x => x.Company)
    .WithRequired(x => x.ImportConnection)

如果 ImportConnection 有一个公司,而公司有一个 ImportConnection,则 EF 将在 Company 上加入此 CompanyId,并在 ImportConnection 上加入 ImportConnectionId。这可能会导致从关系返回预期或不正确数据的问题。

应该是many-to-one连接:

.HasRequired(x => x.Company)
    .WithMany() // Assuming Company does not have a collection of ImportConnections.
    // or .WithMany(x => x.ImportConnections) if it does.

这是我明确配置 EF 而不是依赖约定的原因之一。这样,要么 EF 告诉我存在问题,要么按照我可以检查和更正而不是猜测的方式行事,以及它正在解释什么约定。