光脚丫学LINQ(045):如何表示计算所得列(LINQ to SQL)

视频演示:http://u.115.com/file/f23bcc71be

演示重点
通过为实体类列成员的ColumnAttribute特性添加Expression属性,
就可以使其表示数据表中对应的计算所得列。
而此属性是一个字符串类型的,
赋值给这个属性的值就是数据表中的计算所得列的表达式。
比如这样的表达式:Expression="[UnitPrice] * [UnitsInStock]"
默认情况下,O/R设计器并没有根据数据表的定义而为对应的列成员设置此属性。

在LINQ to SQL的对象模型中,计算所得列都有哪些作用?
这就要分两种情况来看待了:
①当不使用对象模型来创建数据库时:
这种情况实际上就是使用LINQ to SQL来执行一些常规性的数据库操作,
此时,这个Expression属性可有可无,并不会有太大的影响。
但如果包含这个属性的话,当使用LINQ to SQL来更新或添加数据记录的时候,
则会自动获取更新后的计算所得列的值。
这点可以从LINQ to SQL所生成的SQL命令中得知。
②当使用对象模型创建数据库时:
也就是调用DataContext.CreateDatabase()方法创建数据库,
此时这个属性的作用就至关重要了。
它不仅决定了对应的数据列是否是计算所得列,
而且同时也指明了这个计算所得列的计算表达式。
因此,在这种情况下,如果不设置Expression的话,
估计想要生成一个包含了有效的计算所得列的数据表,恐怕就不容易了吧?

并非重点
如果为实体类的列成员设置了ColumnAttribute.Expression,
那就没有必要再设置ColumnAttribute.DbType了,就算不设置,也不会出错的。
如果你设置了,反倒有些不合理了。
既然是由数据库计算来获得值的,到底会是一个怎样的数据范围还真不好说。
如果冒冒然然的就设置的话,你觉得它会合情合理吗?
还有,如果列成员表示为计算所得列,那就不要再将其设置为主键列了。
虽然通常情况下这么做是被允许的,
但是如果使用对象模型来创建数据库的话,
非得给你整出个异常来不可的。
根据异常信息来看,计算所得列并非被设置为可持久性的列,而且很有可能会为空值。
这样的列自然也就不符合主键列的要求了。

关键代码
在下面的代码中将实体类的TotalValue属性设置为表示计算所得列。
其计算表达式为:[UnitPrice] * [UnitsInStock]

[Column(Storage="_TotalValue",
    DbType="Money",
    UpdateCheck=UpdateCheck.Never,
    Expression="[UnitPrice] * [UnitsInStock]")]
public System.Nullable<decimal> TotalValue
{
 get
 {
  return this._TotalValue;
 }
 set
 {
  if ((this._TotalValue != value))
  {
   this.OnTotalValueChanging(value);
   this.SendPropertyChanging();
   this._TotalValue = value;
   this.SendPropertyChanged("TotalValue");
   this.OnTotalValueChanged();
  }
 }
}

光脚丫思考 2011-1-12

原文地址:https://www.cnblogs.com/GJYSK/p/1936496.html