【发布时间】:2012-06-15 17:47:26
【问题描述】:
我正在使用 Entity Framework 4.3(如果 EF 无法满足我的需要,我愿意接受有关更改此设置的建议)。
我有一些实体/业务对象。这些对象不应该改变,不应该被注释(没有 DataAnnotation 属性),不应该为变通方法添加内部成员,并且数据库也是一成不变的/超出我的控制范围。简而言之,数据库不能改变,我的实体也不能。起初,这听起来像是使用 Fluent API 的完美理由。
public class MyEntity
{
public int MyEntityId { get; set; }
public string Name { get; set; }
public bool IsGreen { get; set; }
}
假设这个对象在数据库中所关联的表如下:
CREATE TABLE [dbo].[MyEntities]
(
MyEntityId INT NOT NULL,
Name VARCHAR(30) NOT NULL,
IsGreen CHAR(1) NOT NULL,
ForeignKeyId INT NULL
)
抱歉,如果 SQL 错误,请快速手动输入
希望您会立即注意到一些冲突。
问题 1) 是否可以通过 Fluent API 将我的布尔值映射到 IsGreen CHAR(1) NOT NULL 字段而不添加 解决方法 属性到原始实体?此列不可为空,填充布尔值的表达式可能类似于:
x => new MyEntity() { IsGreen = x.IsGreen == "Y" }
问题 2) 上下文是否允许我将 MyEntity 插入数据库,尽管并非所有列都被映射,只要未映射的列可以为空,即使存在外键?
问题 3)如果 EF 不能做到以上,有没有框架可以做到?
这是我迄今为止尝试过的:
尝试 1: 我开始沿着基于 DB Schema 创建单独的entities 的道路前进,然后创建冗长的表达式以便能够从一个转换到另一个。
这可能最终奏效了,但是忽略它所花费的可笑时间,它产生了一个新问题;我的 where 子句的Expression<Func<MyEntity, bool>> 表达式显然不能再在数据库中应用,而是必须带回所有记录,编译表达式,并将其应用于结果可枚举。
不幸的是,这还不够好,只是带回了太多数据。我本可以花一些时间编写遍历表达式并将 MemberAccess 节点映射到新实体的代码,但这似乎不必要地复杂。
尝试 2:
然后我尝试创建继承的类,这些类可以包含 workaround 属性,在其设置器中设置实际属性,而实际属性通过 fluent API 被忽略。多亏了继承,我前面提到的 where 表达式应该可以工作了。
但是,EF 发现了继承,由于架构与它似乎期望的实体的继承层次不匹配,我不再能够查询数据库。 (我很欣赏这有点含糊,但考虑到 EF 的 TPH/TPT/etc 方面,以及这不一定与我的架构匹配 - 我认为这是我最接近的尝试,但我不知道如何通过流畅的 API)。
尝试 3: 最后,我试图修补设计师。关于那个没什么好说的,除了我不再修补设计师。
注意:该软件需要针对多个不同的数据库运行,这些数据库每次都不会具有完全相同的架构,这就是为什么例如我需要代码才能工作,即使我的模型不一定具有数据库中存在的每一列。不仅如此,而且我不知道,在软件发布之前,数据库可能有多少或哪些额外的列,我只知道这些列是可以为空的,因此我应该能够插入到表中只知道核心非空列(即存在于 MyEntity 对象上的列)。我相信,仅此一项就排除了设计师的可能性。
对不起,文字墙 - 任何帮助表示赞赏!
【问题讨论】:
标签: c# entity-framework .net-4.0 ef-code-first