如何建立非传统的外键关系?

时间:2014-07-16 13:57:08

标签: c# entity-framework ef-code-first entity-framework-6

我正在使用EF 6.1.1 Code First来对付我无法更改的现有架构。我在VisitVisitActivityLog之间存在一对多的关系。

public class Visit
{
    public Guid VisitKey { get; set; }
    public ICollection<VisitActivityLog> VisitActivityLogs { get; set; }
}

public class VisitActivityLog
{
    public Guid LogKey { get; set; }
    public Guid VisitKey { get; set; }
    public Visit Visit { get; set; }
}

public class VisitConfiguration : EntityTypeConfiguration<Visit>
{
    public VisitConfiguration()
    {
        ToTable("Visits");
        HasKey(visit => visit.VisitKey);
    }
}

public class VisitActivityLogConfiruration : EntityTypeConfiguration<VisitActivityLog>
{
    public VisitActivityLogConfiruration()
    {
        ToTable("VisitsActivityLog");
        HasKey(log => log.LogKey);
        HasRequired(log => log.Visit).WithMany().HasForeignKey(log => log.VisitKey);
    }
}

当我尝试查询访问时,我得到以下异常:

SqlException: Invalid column name 'Visit_VisitKey'.Invalid column name 'Visit_VisitKey'.

这是生成的SQL:

SELECT 
    [Project2].[C1] AS [C1], 
    [Project2].[VisitKey] AS [VisitKey], 
    [Project2].[C2] AS [C2], 
    [Project2].[LogKey] AS [LogKey], 
    [Project2].[VisitKey1] AS [VisitKey1], 
    [Project2].[Visit_VisitKey] AS [Visit_VisitKey]
    FROM ( SELECT 
        [Limit1].[VisitKey] AS [VisitKey], 
        [Limit1].[C1] AS [C1], 
        [Extent2].[LogKey] AS [LogKey], 
        [Extent2].[VisitKey] AS [VisitKey1], 
        [Extent2].[Visit_VisitKey] AS [Visit_VisitKey], 
        CASE WHEN ([Extent2].[LogKey] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
        FROM   (SELECT TOP (100) 
            [Extent1].[VisitKey] AS [VisitKey], 
            1 AS [C1]
            FROM [dbo].[Visits] AS [Extent1] ) AS [Limit1]
        LEFT OUTER JOIN [dbo].[VisitsActivityLog] AS [Extent2] ON [Limit1].[VisitKey] = [Extent2].[Visit_VisitKey]
    )  AS [Project2]
    ORDER BY [Project2].[VisitKey] ASC, [Project2].[C2] ASC

如果我从VisitActivityLogs移除Visit媒体资源,我可以查询VisitActivityLog并找到与之关联的Visit

我已阅读这些Microsoft文档12,但我无法确定如何正确配置EF。

1 个答案:

答案 0 :(得分:1)

我们遇到了类似的问题。我们使用.Map()方法解决了它。假设您的外键名为"VisitKey",经过几次实验后,我得到了以下代码。唯一的区别是VisitKey已从VisitActivityLog中删除,外键配置已移至VisitConfiguration

public class Visit
{
    public Guid VisitKey { get; set; }
    public ICollection<VisitActivityLog> VisitActivityLogs { get; set; }
}

public class VisitActivityLog
{
    public Guid LogKey { get; set; }
    public Visit Visit { get; set; }
}

public class VisitConfiguration : EntityTypeConfiguration<Visit>
{
    public VisitConfiguration()
    {
        ToTable("Visits");
        HasKey(visit => visit.VisitKey);
        HasMany(visit => visit.VisitActivityLogs)
            .WithRequired(v => v.Visit)
            .Map(m => m.MapKey("VisitKey"))
            .WillCascadeOnDelete(false);
    }
}

public class VisitActivityLogConfiruration : EntityTypeConfiguration<VisitActivityLog>
{
    public VisitActivityLogConfiruration()
    {
        ToTable("VisitsActivityLog");
        HasKey(log => log.LogKey);
    }
}