6

我正在尝试将遗留数据库映射到实体框架模型。该数据库非常通用,大部分数据都存储在“对象”和“事件”表中。这些列被命名为“Date1”、“Num11”、“Text4”。数据库中没有定义明确的外键。

这是两个表的子集:

CREATE TABLE [Object] (
    [ObjectId] int not null identity(1,1) primary key,
    [ObjectTypeId] int,
    [Name] varchar(100)
);

CREATE TABLE [Event] (
    [EventId] int not null identity(1,1) primary key,
    [EventTypeId] int,
    [Subject] text,
    [Body] text,
    [Date1] datetime,
    [Num11] decimal(18,2)
);

对于 的某些值EventTypeID,该Num11字段引用Object。我可以轻松地在表之间编写连接:

SELECT
    ev.[EventId], ev.[Subject], ev.[Body], ev.[Date1] AS [CreatedDate],
    p.[ObjectId] AS [PersonId], p.[Name] AS [PersonName]
FROM [Event] ev
LEFT JOIN [Object] p ON p.ObjectId = ev.Num11
WHERE ev.[EventTypeId] = 7
AND ev.[Date1] > '2013-04-07'

在实体框架设计器中,我可以为每种类型的对象创建一个单独的实体,并适当地重命名列。当我尝试在实体之间创建导航属性时,问题就开始了,因为外键列类型并不总是与主键匹配。

SQL Server 和实体框架都不允许我在列之间创建外键引用。

当 FK an 和 PK 数据类型不完全匹配时,如何在实体之间创建导航属性?使我能够在 LINQ 查询中包含相关实体的东西,并希望能够在 OData 服务中公开它。

我无法对数据库中的现有表进行任何更改,但如果需要,我可以添加视图。虽然我需要能够将实体保存回数据库。

4

2 回答 2

5

不是一个令人愉快的设计,但还有一些选择。这是你可以做的:

  • Event使用将小数转换为整数的附加列创建 1:1 视图。该属性应标记为已计算。
  • 在与 的 FK 关联中使用该属性Object,因此Object具有EventViewItems映射到视图的导航属性(如果您喜欢)。(您必须在 edmx 设计器中手动添加关联并调整外键字段)。
  • 在一个 linq 语句中读取对象和事件,例如db.Objects.Include(o => o.EventViewItems)

但你不能

  • 将事件添加到db.Objects.EventViewItems,因为您无法写入 FK 字段。
  • 添加事件是db.EventViewItems因为没有为视图定义 InsertFunction。(除非您将视图作为表格侵入模型中)。

因此,您还必须Event在模型中包含原始对象,并使用它来创建/更新/删除 (CUD) 单个Event对象。

感觉有点不稳定,因为您必须注意您的步骤以免遇到运行时异常。另一方面,您将有单独的读取和 CUD 路径。将其称为 CQRS,这种设计突然变得前沿。

于 2013-04-08T12:48:26.973 回答
1

你可以试试这个。将模型中 Num11 的类型更改为整数。在 Event 的配置中,使用 xx.HasColumnType("int") 将 num11 的 databasetyp 设置为 int。

于 2013-04-08T11:15:32.750 回答