微风正在尝试更新一个计算的数据库列 [英] Breeze is trying to update a computed database column

查看:145
本文介绍了微风正在尝试更新一个计算的数据库列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一个朋友报告了一个计算列,实体框架和微风的问题。

A friend reported a problem with a computed column, Entity Framework, and Breeze


我们有一个带有FullName列的表由数据库计算。当创建新的 Person 时,Breeze会将 FullName 属性值发送到服务器,即使它没有被设置,并且在尝试插入新的 Person 实例时触发错误。数据库抛出这个异常:

We have a table with a "FullName" column computed by the database. When creating a new Person, Breeze sends the FullName property value to the server, even though it’s not being set at all, and that triggers an error when trying to insert the new Person instance. The database throws this exception:

FullName列无法修改,因为它是计算列或者是UNION运算符的结果。

以下是SQL Table定义的相关部分:

Here is the relevant portion of the SQL Table definition:


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],'')),
      ...

我的朋友告诉我相应的代码优先类看起来像这样:

My friend tells me the corresponding "Code First" class looks something like this:


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;}
      ...
}

这个问题的答案解释了问题并提供了一个解决方案。

The answer to this question explains the problem and offers a solution.

推荐答案

设计问题



一个计算列为 FullName ,其次,为什么这个属性暴露给客户端。

Design issues

Everyone looking at this wonders why there is a computed column for FullName and, secondarily, why this property is exposed to the client.

让我们假设在那里是计算列的一个很好的原因,这是模型从表中获取值而不是计算值本身的一个很好的理由,也是将其发送给客户端而不是让客户端计算的好理由。这是他告诉我的那个;

Let's just assume there is a good reason for the computed column, a good reason for the model to get the value from the table instead of calculating the value itself, and a good reason to send it to the client rather than have the client calculate it. Here's what he told me about that;


我们需要在查询中包含 FullName $

生活有时会这样做。

请注意, FullName 属性具有公共设置器。用于 Person 类的EF元数据生成器不能指出这是只读属性。 FullName 看起来就像 LastName 。元数据说这是正常的读/写属性。

Notice that the FullName property has a public setter. The EF metadata generator for the Person class cannot tell that this is a read-only property. FullName looks just like LastName. The metadata say "this is normal read/write property."

微风也没有看到差别。客户端应用程序可能无法触及此属性,但是在创建新的 Person 时,Breeze必须为其发送一个值。回到服务器上,Breeze EFContextProvider 认为在创建EF实体时应该通过该值。

Breeze doesn't see a difference either. The client app may not touch this property, but Breeze has to send a value for it when creating a new Person. Back on the server, the Breeze EFContextProvider thinks it should pass that value along when creating the EF entity. The stage is set for disaster.

如果(a)您不能更改表格,(b)您无法更改模型的 FullName 属性定义

What can you do if (a) you can't change the table and (b) you can't change the model's FullName property definition?

EF需要您的帮帮我。您应该告诉EF这实际上是一个数据库计算属性。您可以使用EF流畅界面或使用如下所示的属性:

EF needs your help. You should tell EF that this is actually a database computed property. You could use the EF fluent interface or use the attribute as shown here:


[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public String FullName { get; set; }

添加此属性,EF知道此属性是只读的。它将生成适当的元数据,您可以干净地保存新的 Person 。省略它,你会得到例外。

Add this attribute and EF knows this property is read-only. It will generate the appropriate metadata and you can save a new Person cleanly. Omit it and you'll get the exception.

请注意,这只适用于Code First。如果他生成了数据库优先模型,则EF知道该列已被计算,并且不会尝试设置。

Note that this is only necessary for Code First. If he'd generated the model Database First, EF knows that the column is computed and doesn’t try to set it.

请注意与存储生成的密钥相似的问题。整数键的默认值为存储生成,但Guid键的默认值为客户端生成。如果在表中数据库实际设置了Guid,则必须使用[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Be aware of a similar issue with store-generated keys. The default for an integer key is "store-generated" but the default for a Guid key is "client generated". If, in your table, the database actually sets the Guid, you must mark the ID property with [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

这篇关于微风正在尝试更新一个计算的数据库列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆