问题 从EF模型中删除所需的属性,因为它是只读的


我有一个带有小型数据模型的项目,它以只读方式使用EF模型。

我不想要模型中的完整列集,但如果它们不可为空并且没有默认值,则需要它们。

如何避免包含此类列? 我可以在数据模型中将EF置于某种只读模式,这样我就可以从实体中删除列吗?

我想这样做的原因是因为通过将我的数据模型中的列减少到我需要的数量,我减少了模型需要在查询中返回的列,并且如果模式更改,我降低了破坏数据使用者的风险。

编辑: 我的架构有表格 NOT NULL 列没有默认值。据我所知,我需要将这些列包含在我的edmx中。在我的情况下,我只有只读上下文,所以我不希望这些列完全包含在我的edmx中。

如果我可以阻止列在数据模型中,我可以防止更改架构引起的许多问题。到目前为止,我发现的唯一解决方案是通过指向没有列的“假”数据库来构建数据模型!


7027
2017-07-02 23:57


起源

@GertArnold如果我的桌子有一个 NOT NULL 其中的列没有默认值,我无法从我的edmx中删除它。 Visual Studio会引发生成错误。但是,由于我的数据上下文是只读的,因此我无法插入行并不重要。 - Matthew


答案:


根据MSDN,QueryView专为您描述的场景而设计。

QueryView 映射规范语言(MSL)中的元素定义概念模型中的实体类型或关联与底层数据库中的表之间的只读映射。

您可以定义查询视图以启用以下方案:

在概念模型中定义一个实体,该实体不包括存储模型中实体的所有属性。这包括没有默认值但不支持的属性 空值 值。

...(页面上有更多场景)

你不能使用设计师,但它看起来很简单,可以手工完成。

以下是相关MSDN文档的链接:
https://msdn.microsoft.com/en-us/library/cc716798(v=vs.100).aspx

如果链接失效,请搜索 QueryView MSL


4
2017-07-13 17:54



不幸的是,这不起作用,因为 QueryView 表达与基础模型有关。更改架构阻止我实例化底层模型中的对象:( - Matthew


您在寻找数据注释吗? [NotMapped] ?

如果在模型内的属性中使用它,它将不会传递给db。


3
2017-07-13 16:41



使用它的问题是,如果该列下面的模式发生更改(例如,它从数据库中删除),那么模型在查询时仍然会失败。 - Matthew


如果您愿意使用代码优先代替数据库优先,这可能非常简单。

以微软的示例数据库为例 School。它有一张桌子 Course 有许多必填字段。但是可以只用这些字段的一小部分映射一个类......

class Course
{
    public int CourseID { get; private set; }
    public string Title { get; private set; }
}

...到此表,忽略必填字段 Credits 和 DepartmentID

上下文中的流畅映射 OnModelCreating 覆盖是

modelBuilder.Entity<Course>().HasKey(a => a.CourseID);
modelBuilder.Entity<Course>().Property(a => a.CourseID)
                   .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

如您所见,我使用私有setter定义了属性。 EF没有问题,它与模型的任何消费者进行通信,模型是只读的。

除此之外,您甚至可以将非关键属性映射为 Computed

modelBuilder.Entity<Course>().Property(a => a.Title)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

现在不可能无意中更新任何属性值,因为EF根本不会包含它们 UPDATE 声明。


3
2017-07-13 19:16





我可以防止因更改架构而产生的许多问题。

这最终落后于数据库设计。需要针对您提供的升级方案设计不同的数据库。通过将所述列移出到可空的FK相关表将是可行的选项,EF不需要将来的更改。

但如果它们不可为空并且没有默认值,我需要拥有它们。

EF只能通过其设计尽职尽责地报告数据库中的内容。

任何架构更改都可能会影响许多因素,例如新约束,触发器和整体表更改。隐藏设计师中的列,然后希望它适用于 不同的架构-d 数据库并不明智。

我个人遇到了不同步的EF设计模型,并且存在可能以奇怪的方式影响代码的逻辑错误。

如果架构发生更改,我可以降低破坏数据使用者的风险。

这些究竟是怎么回事 消费者 访问数据?

任何真正的消费者都应该通过webservice或工厂模式访问层,其中数据应该只返回为 Interface 类型数据对象。因此,当/如果数据库或模式发生更改时,返回的接口会发生/不会更改;因此,无论使用何种具体对象,架构更新都不会破坏接口背后的任何消费者安全。

这不是你想要的答案,但这为实现同一目标提供了两种选择。


3
2017-07-13 19:16



资源库模糊其数据访问模式是返回只读域对象。最终消费者不知道EF是底层数据模式。问题是我可能会将完全多余的列更改为资源库,并且无法在其DAL中实例化对象,因为数据模型不再与架构匹配。 - Matthew
@Matthew Fair足够...然后它回退到数据库设计前面,以划分任何未来的更改或手动修改模板;这再次没有真正回答你的问题。值得深思。谢谢。 - ΩmegaMan


您还可以通过从edmx存储模型部分删除不需要的属性来解决此问题。


0
2018-03-23 16:00