EF4 CTP5 代码优先实现中的实体拆分场景
Posted
技术标签:
【中文标题】EF4 CTP5 代码优先实现中的实体拆分场景【英文标题】:Entity-splitting scenario in EF4 CTP5 code-first implementation 【发布时间】:2011-03-17 17:28:07 【问题描述】:我认为我正在寻找的实际上是实体分割。但是,我不能 100% 确定我需要的方式是否受支持。因此,我将添加大量细节,希望对您有所帮助。我会将范围限制为一个实体,因为我必须处理的所有实体的答案都是相同的。
所以,我有一个用户实体:
User
ID (int)
CustID (int)
CustomerString (string)
FirstName (string)
LastName (string)
Email (string)
由于我们的数据库是多租户的,每个对象都有与之相关联的所有者的概念。这由所有表中的 CustID 表示。但是,对于将访问此数据服务的客户来说,此 ID 是一个毫无意义的 PK。他们知道他们的 CustomerString,这只是一个唯一的字符串值,等同于我们 Client 表中的 ID。
与User实体相关的两个表如下:
客户
CREATE TABLE [Customers](
[ID] [int] NOT NULL,
[Name] [varchar](100) NOT NULL,
[Description] [varchar](255) NULL,
[ClientPhone] [varchar](20) NULL,
[Address] [varchar](255) NULL,
[CustomerString] [varchar](100) NOT NULL,
[sys_CreateDate] [datetime] NOT NULL,
[sys_LastUpdate] [datetime] NOT NULL,
CONSTRAINT [PK_Customers] PRIMARY KEY NONCLUSTERED
(
[ID] ASC
)
用户
CREATE TABLE [Users](
[UserID] [int] IDENTITY(2000000,1) NOT NULL,
[CustID] [int] NOT NULL,
[FirstName] [varchar](40) NOT NULL,
[LastName] [varchar](40) NOT NULL,
[mail] [varchar](255) NULL,
[CreateDate] [datetime] NOT NULL,
[ModifyDate] [datetime] NOT NULL,
CONSTRAINT [PK2_Users] PRIMARY KEY CLUSTERED
(
[UserID] ASC
)
所以,目前,我将 User 实体映射到 Users 表,如下所示:
ID ==> Users.UserID
CustID ==> Users.CustID
CustomerString <NOT MAPPED>
FirstName ==> Users.FirstName
LastName ==> Users.LastName
Email ==> Users.Mail
现在,我的症结来了。我需要将 CustomerString 映射到 Customers.CustomerString,其中 Users.CustID = Customers.ID。在我看来,根据我的阅读,如果每个表中的 ID 命名相同,这将不是问题。但是,如您所见,情况并非如此。
请帮忙!这是我过去一个月左右一直在工作的这个项目的绝对要求。
提前感谢您提供的任何帮助!
瑞恩
【问题讨论】:
User.CustomerString 可以是只读字符串吗? 【参考方案1】:我认为这是不可能的。第一个问题是 EF 不能使用唯一键(可能是available in next major version)。因此,您不能在 Customer->Id 和 User->CustId 之间强制执行 1:1 关系(这需要唯一键约束)。要在 EF 中启用 1:1 关系,实体必须“共享”PK。这意味着您只能在您显然不想要的 Customer->Id 和 User->Id 上创建 1:1 关系。
第二个问题是生成的 User 类不是实体。它不包含两个类的所有列。它是这两个实体的投影。您可以使用这两个实体并创建自定义 linq 查询来投影到这个只读类,例如:
var query = from u in context.Users
join c in context.Customers on u.CustId equals c.Id
select new UserProjection
Id = u.Id,
CustId = c.Id,
CustomerString = c.CustomerString,
FirstName = u.FistName,
LastName = u.LastName
Email = u.Mail
;
另外请注意,CTP5 已经过时。 EF 4.1 RC 是 relased two days ago。
【讨论】:
我实际上注意到 4.1 发布后发布。 我不完全理解您关于这不是一个实体的评论,因为用户不包含两个表中的所有字段。这真的是 EF 中实体的要求吗?它似乎立即破坏了建模数据以匹配您的业务实体的目的。 db 表实际上多久部分或全部反映您的业务实体?它们通常由从不同表中提取的数据组成,但通常不是全部。 (想想在查找表上创建/修改日期或 pks。) @Rocky:问题是您的用户类不包含映射表中的所有不可为空的列。因此,您的应用程序将永远无法插入用户。 啊,我明白你在说什么。我仍然很好奇这是否是一项要求,尽管这纯粹是一项只读服务,并且永远不会针对此模型执行更新/插入/删除?感谢您的反馈!以上是关于EF4 CTP5 代码优先实现中的实体拆分场景的主要内容,如果未能解决你的问题,请参考以下文章