Entity framework Breeze正在尝试更新计算数据库列
一位朋友报告了计算列、实体框架和Breeze的问题 我们有一个由数据库计算的带有“FullName”列的表。创建新的Entity framework Breeze正在尝试更新计算数据库列,entity-framework,breeze,Entity Framework,Breeze,一位朋友报告了计算列、实体框架和Breeze的问题 我们有一个由数据库计算的带有“FullName”列的表。创建新的人员时,Breeze将全名属性值发送到服务器,即使它根本没有被设置,并且在尝试插入新的人员实例时会触发错误。数据库引发此异常: 无法修改列“FullName”,因为它是计算列或是UNION运算符的结果。 以下是SQL表定义的相关部分: CREATE TABLE [dbo].[Person]( [ID] [bigint] IDENTITY(1,1) NOT NULL,
人员
时,Breeze将全名
属性值发送到服务器,即使它根本没有被设置,并且在尝试插入新的人员
实例时会触发错误。数据库引发此异常:
无法修改列“FullName”,因为它是计算列或是UNION运算符的结果。
以下是SQL表定义的相关部分:
CREATE TABLE [dbo].[Person](
[ID] [bigint] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](100) NULL,
[MiddleName] [varchar](100) NULL,
[LastName] [varchar](100) NOT NULL,
[FullName] AS ((([Patient].[LastName]+',') + isnull(' '+[Patient].[FirstName],'')) + isnull(' '+[Patient].[MiddleName],'')),
...
创建表[dbo].[Person](
[ID][bigint]标识(1,1)不为空,
[FirstName][varchar](100)空,
[MiddleName][varchar](100)空,
[LastName][varchar](100)不为空,
[FullName]AS((([Patient].[LastName]+',')+isnull('+[Patient].[FirstName],''))+isnull('+[Patient].[MiddleName],''),
...
我的朋友告诉我相应的“代码优先”类如下所示:
public class Person {
public int ID {get; set;}
public string FirstName {get; set;}
public string MiddleName {get; set;}
public string LastName {get; set;}
public string FullName {get; set;}
...
}
公共阶层人士{
公共int ID{get;set;}
公共字符串名{get;set;}
公共字符串MiddleName{get;set;}
公共字符串LastName{get;set;}
公共字符串全名{get;set;}
...
}
此问题的答案解释了问题并提供了解决方案。设计问题
每个人都想知道为什么FullName
会有一个计算列,其次,为什么这个属性会向客户机公开
让我们假设计算列有很好的理由,模型有很好的理由从表中获取值而不是计算值本身,还有很好的理由将其发送给客户机而不是让客户机计算
“我们需要在查询中包含全名
”
生活有时就是这样
后果
请注意,FullName
属性有一个公共setter。Person
类的EF元数据生成器无法判断这是只读属性。FullName
看起来就像LastName
。元数据说“这是正常的读/写属性。”
Breeze也没有看到任何区别。客户端应用程序可能不会触及此属性,但Breeze在创建新的人员时必须为其发送一个值。回到服务器上,BreezeEFContextProvider
认为在创建EF实体时应该传递该值。该阶段设置为灾难
如果(a)您不能更改表,并且(b)您不能更改模型的FullName
属性定义,您可以做什么
解决办法
EF需要您的帮助。您应该告诉EF这实际上是一个数据库计算属性。您可以使用EF fluent接口或使用如下所示的属性:
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public String FullName { get; set; }
[数据库生成(DatabaseGeneratedOption.Computed)]
公共字符串全名{get;set;}
添加此属性,EF就会知道此属性是只读的。它将生成相应的元数据,您可以干净地保存新的人员。忽略它,您将获得异常
注意,这只对代码优先是必需的。如果他首先生成了模型数据库,EF知道该列是计算出来的,不会尝试设置它
请注意存储生成的键也存在类似问题。整数键的默认值为“存储生成”,但Guid键的默认值为“客户端生成”。如果在表中,数据库实际设置了Guid,则必须使用[DatabaseGenerated(DatabaseGenerateOptions.Identity)]标记ID
属性