C# EF代码优先:具有不同键名的关系

C# EF代码优先:具有不同键名的关系,c#,sql,linq,entity-framework,entity-framework-6.1,C#,Sql,Linq,Entity Framework,Entity Framework 6.1,我有两张桌子: DocumentSet: setId (int) name (varchar(50)) DocIdentifier: docIdId (int) docSetId (int) <-- (setId from DocumentSet) customId (char(9)) 请注意命名差异:setId和docSetId是用于外键的列。当我尝试在实体框架中复制这个时,问题就出现了。我有明显的模式: class DocumentSet { public int Id {

我有两张桌子:

DocumentSet:
setId (int)
name (varchar(50))

DocIdentifier:
docIdId (int)
docSetId (int) <-- (setId from DocumentSet)
customId (char(9))
请注意命名差异:
setId
docSetId
是用于外键的列。当我尝试在实体框架中复制这个时,问题就出现了。我有明显的模式:

class DocumentSet {
    public int Id {get;set;}
    public string Name {get;set;}
    public virtual ICollection<DocumentIdentifier> Identifiers {get;set;}
}

class DocumentIdentifier {
    public int Id {get;set;}
    public int SetId {get;set;}
    public string CustomId {get;set;}
    public DocumentSet DocSet {get;set;}
}
问题是:当我发送这样的LINQ查询时:

_context.Set<DocumentSet>().Where(d => d.DocumentIdentifiers.Any(pt=>pt.CustomId == customId)).Single();
我猜问题在于
setId
docSetId
是不同的名称,但我似乎不知道如何让EF看到
[Extent2].[DocumentSet\u Id]
应该是
[Extent2].[docSet\u Id]
。在
DocumentIdentifierTypeConfiguration
中是否有我遗漏的东西可以帮助EF理解这一点?我认为行
属性(f=>f.SetId)
会这样做,但显然不会

简言之,我该怎么说

`DocumentSet has many DocumentIdentifiers with a foreign key relationship of DocumentSet.setId = DocIdentifier.docSetId`?
尝试添加和删除

完整代码

public class AppContext : DbContext
{
    public DbSet<DocumentSet> DocumentSets { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new DocumentSetTypeConfiguration());
        modelBuilder.Configurations.Add(new DocumentIdentifierTypeConfiguration());
    }
}
public class DocumentSetTypeConfiguration : EntityTypeConfiguration<DocumentSet>
{
    public DocumentSetTypeConfiguration()
    {
        HasKey(f => f.Id);
        Property(f => f.Id).HasColumnName("setId");
        HasMany(f => f.DocumentIdentifiers).WithRequired().HasForeignKey(x => x.SetId);
    }
}
public class DocumentIdentifierTypeConfiguration : EntityTypeConfiguration<DocumentIdentifier>
{
    public DocumentIdentifierTypeConfiguration()
    {
        ToTable("DocIdentifier");
        HasKey(f => f.Id);
        Property(f => f.Id).HasColumnName("docIdId");
        Property(f => f.SetId).HasColumnName("docSetId");
    }
}
public class DocumentSet
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<DocumentIdentifier> DocumentIdentifiers { get; set; }
}
public class DocumentIdentifier
{
    public int Id { get; set; }
    public int SetId { get; set; }
    public string CustomId { get; set; }
}

这很好(经过一些修改,见我的答案)。现在我必须弄清楚为什么EF突然不再实际连接到数据库…@StephenCollins,你不必添加
DocSet
(但如果你愿意,你可以),只要尝试添加上面的代码,它就可以工作,
WithRequired
可以在指定
HasMany
后接受空参数,如果使用
MapKey
,则类
public int SetId{get;set;}
中的外键值将不会作为外键连接。您的建议听起来不错,但问题还是在于命名。您的建议给我带来了一个
modelvalidateexception
,而
MapKey
方法将正确生成模型/查询,但问题在于:
有许多(ds=>ds.Identifiers).WithRequired().Map(di=>di.MapKey(“docSetId”)。这会失败,因为它告诉我`类型中的每个属性名称都必须是唯一的。属性名“docSetId”已经定义。`@StephenCollins,我发布了完整的代码和结果,您能指出缺少什么吗?您的代码在新项目中运行良好。我必须有我的代码中没有注意到的其他问题。我还有更多的挖掘工作要做。非常感谢。
SELECT TOP (2) 
    [Extent1].[SetId] AS [SetId], 
    [Extent1].[Name] AS [Name]
    FROM [dbo].[DocumentSet] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM [dbo].[DocIdentifier] AS [Extent2]
        WHERE ([Extent1].[SetId] = [Extent2].[DocumentSet_Id]) AND (([Extent2].CustomId = @p__linq__0) OR (([Extent2].[CustomId] IS NULL) AND (@p__linq__0 IS NULL)))
    )
`DocumentSet has many DocumentIdentifiers with a foreign key relationship of DocumentSet.setId = DocIdentifier.docSetId`?
HasMany(f => f.Identifiers).WithRequired().HasForeignKey(x => x.SetId);
public class AppContext : DbContext
{
    public DbSet<DocumentSet> DocumentSets { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new DocumentSetTypeConfiguration());
        modelBuilder.Configurations.Add(new DocumentIdentifierTypeConfiguration());
    }
}
public class DocumentSetTypeConfiguration : EntityTypeConfiguration<DocumentSet>
{
    public DocumentSetTypeConfiguration()
    {
        HasKey(f => f.Id);
        Property(f => f.Id).HasColumnName("setId");
        HasMany(f => f.DocumentIdentifiers).WithRequired().HasForeignKey(x => x.SetId);
    }
}
public class DocumentIdentifierTypeConfiguration : EntityTypeConfiguration<DocumentIdentifier>
{
    public DocumentIdentifierTypeConfiguration()
    {
        ToTable("DocIdentifier");
        HasKey(f => f.Id);
        Property(f => f.Id).HasColumnName("docIdId");
        Property(f => f.SetId).HasColumnName("docSetId");
    }
}
public class DocumentSet
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<DocumentIdentifier> DocumentIdentifiers { get; set; }
}
public class DocumentIdentifier
{
    public int Id { get; set; }
    public int SetId { get; set; }
    public string CustomId { get; set; }
}
SELECT TOP (2) 
    [Extent1].[setId] AS [setId], 
    [Extent1].[Name] AS [Name]
FROM [dbo].[DocumentSets] AS [Extent1]
WHERE  EXISTS (SELECT 
    1 AS [C1]
    FROM [dbo].[DocIdentifier] AS [Extent2]
    WHERE ([Extent1].[setId] = [Extent2].[docSetId])
    AND   (([Extent2].[CustomId] = @p__linq__0) 
          OR (([Extent2].[CustomId] IS NULL) AND (@p__linq__0 IS NULL)))
)