我正在使用Code First定义现有数据库的架构。我遇到的问题是它们在表中的键名不太一致。这对一对多关系很好,因为我可以使用该HasForeignKey()
方法,但是一对一关系似乎并不等效。我的表定义是:
namespace Data.Mappings {
internal class DocumentTypeConfiguration : EntityTypeConfiguration<Document> {
public DocumentTypeConfiguration() {
ToTable("ProsDocs");
HasKey(m => m.Id);
Property(m => m.Id)
.HasColumnName("ProsDocId")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// ---- This is the foreign key ----
Property(m => m.TypeId)
.HasColumnName("ProsDocTypeId")
.HasMaxLength(3);
HasRequired(d => d.DocType)
.WithRequiredDependent(dt => dt.Document);
// I need to specify here that the foreign key is named "DocTypeId" and not "DocType_Id"
}
}
internal class DocTypeTypeConfiguration : EntityTypeConfiguration<DocType> {
public DocTypeTypeConfiguration() {
ToTable("DocType");
HasKey(m => m.Id);
// ---- This is the "child" end of the foreign key ----
Property(m => m.Id)
.HasColumnName("DocTypeId")
.HasMaxLength(4);
Property(m => m.FullName)
.HasColumnName("DocTypeDesc")
.HasMaxLength(255);
Property(m => m.Priority)
.HasColumnName("DocPriority");
// Or would it be easier to define it here?
// HasRequired(m => m.Document)
// .WithRequiredDependent(d => d.DocType);
}
}
}
为了阐明模型,每个模型Document
都有一个DocType
,具有的外键关系Document.ProsDocTypeId --> DocType.Id
。
有没有一种方法可以定义一对一关系的键的列名?
编辑:我想我的架构不清楚。
dbo.DocType
-----------
DocTypeId char(4) (PK)
DocTypeDesc varchar(255)
dbo.ProsDocs
------------
ProsDocId int (PK)
ProsDocTypeId char(4)
基本上,我需要结果查询如下所示:
SELECT
[Extent1].[ProsDocId] AS [ProsDocId],
[Extent2].[DocTypeId] AS [DocTypeId]
FROM [dbo].[ProsDocs] AS [Extent1]
LEFT OUTER JOIN [dbo].[DocType] AS [Extent2] ON [Extent1].[ProsDocTypeId] = [Extent2].[DocTypeId]
WHERE [Extent1].[ProsId] = @EntityKeyValue1
但是相反,由于EF假定我要使用主键(dbo.ProsDocs.ProsDocId
)而不是外键(dbo.ProsDocs.DocTypeId
),因此它生成的查询是这样的:
SELECT
[Extent1].[ProsDocId] AS [ProsDocId],
[Extent2].[DocTypeId] AS [DocTypeId]
FROM [dbo].[ProsDocs] AS [Extent1]
LEFT OUTER JOIN [dbo].[DocType] AS [Extent2] ON [Extent1].[ProsDocId] = [Extent2].[ProsDocTypeId]
WHERE [Extent1].[ProsId] = @EntityKeyValue1
区别在于:
理想查询:
LEFT OUTER JOIN [dbo].[DocType] AS [Extent2] ON [Extent1].[ProsDocTypeId] = [Extent2].[DocTypeId]
当前查询:
LEFT OUTER JOIN [dbo].[DocType] AS [Extent2] ON [Extent1].[ProsDocId] = [Extent2].[ProsDocTypeId]
我需要在和之间建立一对一的关系。EF遇到的问题是它只想使用主键而不是外键来创建关系。如何指定外键的列名,以使每个外键都只有一个?dbo.ProsDocs.ProsDocTypeId
dbo.DocType.DocTypeId
Document
DocType
如果theDocument
是委托人,并且DocType
是从属人,那么您要么需要
启用此配置 Document
HasRequired(d => d.DocType).WithRequiredPrincipal(dt => dt.Document);
还是这个配置上 DocType
HasRequired(dt => dt.Document).WithRequiredDependent(d => d.DocType);
并从中删除TypeId
/ProsDocTypeId
属性,Document
因为主体不能具有要依赖的外键ID,除非不是约束,而是普通列。
更新
实体:
public class Document
{
public string Id { get; set; }
// This entity is a principal. It can't have foreign key id to dependent.
// public string TypeId { get; set; }
public DocType DocType { get; set; }
}
Linq:
db.Documents.Include(d => d.DocType)
询问:
SELECT
1 AS [C1],
[Extent1].[ProsDocId] AS [ProsDocId],
[Extent2].[DocTypeId] AS [DocTypeId],
FROM [dbo].[ProsDocs] AS [Extent1]
LEFT OUTER JOIN [dbo].[DocType] AS [Extent2] ON [Extent1].[ProsDocId] = [Extent2].[DocTypeId]
更新2
为了实现理想的查询,您需要的关系是一对多的。一个DocType
可以有很多Document
。
public class Document
{
public string Id { get; set; }
public string TypeId { get; set; }
public DocType DocType { get; set; }
}
public class DocType
{
public string Id { get; set; }
public string FullName { get; set; }
public string Priority { get; set; }
public ICollection<Document> Documents { get; set; }
}
上的配置Document
。
更改此:
HasRequired(d => d.DocType).WithRequiredDependent(dt => dt.Document);
进入:
HasRequired(d => d.DocType).WithMany(dt => dt.Documents).HasForeignKey(d => d.TypeId);
Linq:
db.Documents.Include(d => d.DocType)
询问:
SELECT
1 AS [C1],
[Extent1].[ProsDocId] AS [ProsDocId],
[Extent1].[ProsDocTypeId] AS [ProsDocTypeId],
[Extent2].[DocTypeId] AS [DocTypeId],
FROM [dbo].[ProsDocs] AS [Extent1]
INNER JOIN [dbo].[DocType] AS [Extent2] ON [Extent1].[ProsDocTypeId] = [Extent2].DocTypeId]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句