【问题标题】:Entity Framework, Existing Database, Code First - Ignoring Db Columns and Changing Datatypes实体框架、现有数据库、代码优先 - 忽略 Db 列和更改数据类型
【发布时间】: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


    【解决方案1】:

    答案 1:否。EF 目前不支持将 char(1) 映射到 bool。你可以投票给my suggestion

    答案 2:是的,如果所有非映射列都可以为空或定义了默认值约束。

    答案 3:NHibernate

    【讨论】:

    • 谢谢@Ladislav。我对你的建议投了赞成票,完全同意。过去,我在 SO 上看到了很多“EF 是垃圾,使用 NHibernate”cmets,但通常没有太多的理由。您是否可以为示例MyEntity 提供实现上述所有要求所需的代码的快速示例?
    • 另外,值得注意的是,我遇到的关于 Fluent NHibernate 的第一个教程,明确指出实体的属性必须是虚拟的。这已经与我的要求相冲突(无法更改实体)。
    • 如果您想要延迟加载等高级 ORM 功能,则需要虚拟属性。您最初的问题是关于 EF,因此为 NHibernate 放置样本是不合适的。
    • 原始问题的第一行确实指出,如果 EF 无法满足我的需求,欢迎使用 EF 的替代品。不过,如果您没有时间提供示例,我理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2015-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多