繁体   English   中英

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

[英]EF Code First: Relationships with differing key names

我有两个表:

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

DocIdentifier:
docIdId (int)
docSetId (int) <-- (setId from DocumentSet)
customId (char(9))

在两个表上完成的典型查询在SQL中如下所示:

SELECT ds.name
FROM DocumentSet ds
INNER JOIN DocIdentifiers di ON ds.setId = di.docSetId
WHERE di.customId == 'someId'

注意命名差异: setIddocSetId是用于外键的列。 当我尝试在Entity Framework中复制此问题时,就会出现问题。 我有明显的模型:

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;}
}

同样,为了清楚起见,在代码上有些命名差异。 所以我为这两个创建EntityTypeConfiguration

internal class DocumentSetTypeConfiguration : EntityTypeConfiguration<DocumentSet> {
    public DocumentSetTypeConfiguration () {
        HasKey(f => f.Id);
        Property(f => f.Id).HasColumnName("setId");
        HasMany(f => f.DocumentIdentifiers);
    }
}

internal class DocumentIdentifierTypeConfiguration : EntityTypeConfiguration<DocumentIdentifier> {
    public DocumentIdentifierTypeConfiguration () {
        ToTable("DocIdentifier");
        HasKey(f => f.Id);
        Property(f => f.Id).HasColumnName("docIdId");
        Property(f => f.SetId).HasColumnName("docSetId");
    }
}

这是问题所在:当我发送这样的LINQ查询时:

_context.Set<DocumentSet>().Where(d => d.DocumentIdentifiers.Any(pt=>pt.CustomId == customId)).Single();

生成的内容有些拙劣:

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)))
    )

我的猜测是问题在于setIddocSetId是不同的名称,但是我似乎无法弄清楚如何让EF看到[Extent2].[DocumentSet_Id]应该是[Extent2].[docSet_Id] 我在DocumentIdentifierTypeConfiguration中缺少什么可以帮助EF理解这一点吗? 我认为该行Property(f => f.SetId).HasColumnName("docSetId"); 会这样做,但显然不会。

简而言之,我怎么说

`DocumentSet has many DocumentIdentifiers with a foreign key relationship of DocumentSet.setId = DocIdentifier.docSetId`?

尝试添加WithRequiredHasForeignKey

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)))
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM