当数据类型在实体框架中不匹配时,导航属性

本文关键字:导航 属性 不匹配 数据类型 实体 框架 | 更新日期: 2023-09-27 18:07:55

我正试图将遗留数据库映射到实体框架模型。数据库非常通用,大多数数据存储在"Object"answers"Event"表中。列被命名为"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和PK数据类型不完全匹配时,我如何在实体之间创建导航属性?使我能够在LINQ查询中包含相关实体,并希望能够在OData服务中公开它的东西。

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

当数据类型在实体框架中不匹配时,导航属性

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

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

但你不能

  • 添加事件到db.Objects.EventViewItems,因为你不能写入FK字段
  • 添加事件到db.EventViewItems,因为没有为视图定义InsertFunction。(除非你把视图作为表插入模型)。

所以你必须在模型中也包括原始的Event,并使用它来创建/更新/删除(CUD)单个Event对象。

感觉有点不稳定,因为您必须注意您的步骤,以免遇到运行时异常。另一方面,您将为读取和CUD提供单独的路径。叫它CQRS,这个设计突然就成为了最前沿。

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