我有一个小型数据模型项目,它以只读方式使用EF模型。
我不想要模型中的完整列,但如果它们不可为空并且没有默认值,我需要拥有它们。
如何避免包含此类列? 我可以在数据模型中将EF置于某种只读模式,这样我就可以从实体中删除列吗?
我想这样做的原因是因为通过将我的数据模型中的列减少到我需要的数量,我减少了模型需要在查询中返回的列,并且如果模式更改,我可以降低破坏数据使用者的风险
编辑:我的架构中包含NOT NULL
列的表,没有默认值。据我所知,我需要将这些列包含在我的edmx中。在我的情况下,我只有只读上下文,所以我不希望这些列完全包含在我的edmx中。
如果我可以阻止列在数据模型中,我可以防止因更改架构而产生的许多问题。到目前为止,我发现的唯一解决方案是通过指向"假的"来构建数据模型。数据库没有列!
答案 0 :(得分:4)
根据MSDN,QueryView专为您描述的场景而设计。
映射规范语言(MSL)中的 QueryView 元素定义了概念模型中的实体类型或关联与底层数据库中的表之间的只读映射。
您可以定义查询视图以启用以下方案:
在概念模型中定义一个实体,该实体不包含存储模型中实体的所有属性。这包括没有默认值且不支持 null 值的属性。
...(页面上的更多场景)
你不能使用设计师,但它看起来很简单,可以手工完成。
以下是相关MSDN文档的链接:
https://msdn.microsoft.com/en-us/library/cc716798(v=vs.100).aspx
如果链接失效,请搜索QueryView MSL
。
答案 1 :(得分:3)
您在寻找数据注释[NotMapped]
吗?
如果在模型内的属性中使用它,它将不会传递给db。
答案 2 :(得分:3)
如果您愿意使用代码优先代替数据库优先,这可能非常简单。
以微软的示例数据库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);
如您所见,我使用私有设置器定义了属性。 EF没有任何问题,它与模型的任何消费者进行通信,该模型是只读的。
除此之外,您甚至可以将非关键属性映射为Computed
:
modelBuilder.Entity<Course>().Property(a => a.Title)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
现在无法无意中更新任何属性值,因为EF根本不会在UPDATE
语句中包含它们。
答案 3 :(得分:3)
我可以防止因更改架构而产生的许多问题。
最终落后于数据库设计。需要针对您提供的升级方案设计不同的数据库。通过将所述列移出到可空的FK相关表将是一个可行的选项,EF无需将来进行更改。
但如果它们不可为空并且没有默认值,我需要拥有它们。
EF只能通过其设计尽职尽责地报告数据库中的内容。
任何架构更改都可能影响许多因素,例如新约束,触发器和整体表更改。在设计器中隐藏列然后希望它在不同的schema-d 数据库上工作是不明智的。
我个人遇到了不同步的EF设计模型,并且存在可能以奇怪的方式影响代码的逻辑错误。
如果架构发生变化,我会降低破坏数据使用者的风险。
这些消费者究竟是如何访问数据的?
任何真正的消费者都应该通过Web服务或工厂模式访问层,其中数据只应作为Interface
类型数据对象返回。因此,当/如果数据库或模式发生更改时,返回的接口不会更改;因此,无论使用何种具体对象,架构更新都不会破坏接口背后的任何消费者安全。
这不是你想要的答案,但这为实现同一目标提供了两种选择。
答案 4 :(得分:0)
您还可以通过从edmx存储模型部分删除不需要的属性来解决此问题。