我有一個預先存在的數據模型,最初使用EF 4來訪問。更新到EF 6,遇到配置語法更改的問題,並定義要正確查詢的關係。實體框架Fluent API在相關對象上的sql中生成額外的列
在這種特定的情況下,我的外鍵關係是在SQL生成兩列,一個我定義,一個不知從何處......
我有以下兩個對象 - 公司與APPUSER:
public class Company : EntityBase, IComparable<Company>
{
public string Name { get; set; }
public virtual IList<AppSystem> AppSystems { get; set; }
public virtual IList<AppUser> AppUsers { get; set; }
public string PortalCustomerName { get; set; }
}
public class AppUser : EntityBase
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public virtual Company Company { get; set; }
public FlowStatus FlowStatus { get; set; }
public virtual IList<AppUserRole> AppUserRoles { get; set; }
}
public abstract class EntityBase
{
/// <summary>
/// The id assigned by the system.
/// </summary>
public virtual int Id { get; set; }
}
配置爲兩類:
public class CompanyConfiguration : EntityTypeConfiguration<Company>
public CompanyConfiguration()
{
ToTable("Company");
Property(c => c.Id).HasColumnName("CompanyID");
Property(c => c.Name).HasMaxLength(50).IsRequired();
Property(c => c.PortalCustomerName).HasMaxLength(50).IsRequired();
HasMany(c => c.AppSystems);
HasMany(c => c.AppUsers);
}
}
public class AppUserConfiguration : EntityTypeConfiguration<AppUser>
{
/// <summary>
/// Initializes a new instance of the <see cref="AppUserConfiguration"/> class with default values.
/// </summary>
public AppUserConfiguration()
{
ToTable("AppUser");
Property(u => u.Id).HasColumnName("AppUserId");
Property(u => u.Email).HasMaxLength(256).IsRequired();
Property(u => u.FirstName).HasMaxLength(50);
Property(u => u.LastName).HasMaxLength(50);
Property(u => u.FlowStatus.Value).HasColumnName("FlowStatus");
HasRequired(u => u.Company).WithMany().Map(m => m.MapKey("CompanyID"));
}
}
當我查詢的公司,沒問題,我得到一個匹配
SELECT
[Extent1].[CompanyID] AS [CompanyID],
[Extent1].[Name] AS [Name],
[Extent1].[PortalCustomerName] AS [PortalCustomerName]
FROM [dbo].[Company] AS [Extent1]
WHERE N'Joe''s Diner' = [Extent1].[Name]
ORDER BY [Extent1].[Name] ASC
但是SQL,當我詢問我在與查詢問題AppUsers。通過上面的配置中,我得到一個正確的請求CompanyId但我也得到一個額外的列,Company_Id1:
SELECT
[Extent1].[AppUserId] AS [AppUserId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Email] AS [Email],
[Extent1].[FlowStatus] AS [FlowStatus],
[Extent1].[CompanyID] AS [CompanyID],
**[Extent1].[Company_Id1] AS [Company_Id1]**
FROM [dbo].[AppUser] AS [Extent1]
WHERE ([Extent1].[AppUserId] > 0) AND (N'Joe' = [Extent1].[LastName])
但如果我刪除映射和剛剛結束了「的hasMany()」的配置,正確的地圖消失,Company_Id1變成「Company_Id」:
SELECT
[Extent1].[AppUserId] AS [AppUserId],
[Extent1].[FirstName] AS [FirstName],
[Extent1].[LastName] AS [LastName],
[Extent1].[Email] AS [Email],
[Extent1].[FlowStatus] AS [FlowStatus],
[Extent1].[Company_Id] AS [Company_Id]
FROM [dbo].[AppUser] AS [Extent1]
WHERE ([Extent1].[AppUserId] > 0) AND (N'Joe' = [Extent1].[LastName])
我的配置有什麼問題?
感謝您的詳細解釋 - 你可以看到我解決了這個問題,但我不是原因不清楚。你的解釋澄清 - 我只需要在一個地方定義關係。遵循這一思路,我完全從AppUserConfiguration中刪除了對公司的引用,並在公司中保留了定義並獲得了相同的SQL。這就是說 - 關於何處正確定義關係的想法是什麼?我認爲,在「孩子」(用戶)依賴於「父母」(公司)的情況下,該關係在「孩子」中會更好地定義。 –
WRT導航 - 在這種情況下,如果我們在所有實體之間導航,它將從一個用戶到另一個公司,從而進一步強調,至少在這種情況下,關係定義屬於用戶(最終是AppSystems - 一旦我得到在我移植物體時將其重新合併到我的項目中......) –
正如我所提到的,當您有雙向導航時,這只是一個品味問題。但是當你有單向導航的時候(有些人只把集合,只有一些引用),那麼你必須從具有導航屬性的實體開始 - 「Has'方法需要屬性訪問器,'With'具有無參數的重載。 –