CodeFluent尝试在删除相关实体时使用NULL更新bigint类型的非可空外键

时间:2016-07-05 17:58:12

标签: codefluent

在我的模型中,我使用bigint(ulong)作为实体键的类型。 值0必须用于空键。 外键的列不能为空,因为在我的方法中,我只想检查值0而不是null。 除了删除其他实体引用的相关实体外,一切正常。

这是我的模特:

<cf:entity name="Customer" cfom:bindingList="false">
  <!--persistenceIdentity is true, because the corresponding column for this property must be auto incremented by the database.-->
  <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />
  <cf:property name="Name" typeName="string" />
</cf:entity>

<cf:entity name="Order" cfom:bindingList="false">
  <!--persistenceIdentity is true, because the corresponding column for this property must be auto incremented by the database.-->
  <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />

  <!--persistenceNullable is false, because the column for the foreign key must not be nullable.-->
  <cf:property name="Customer" typeName="{0}.Customer" persistenceNullable="false" />
</cf:entity>

这是我的代码:

Customer customer = new Customer();
customer.Save();
Order order = new Order();
order.Customer = customer;
order.Save();
customer.Delete();

最后一条语句给出以下错误: 无法将值NULL插入列&#39; Order_Customer_Id&#39;,table&#39; CodeFluentTest.dbo.Order&#39 ;;列不允许空值。更新失败。

这是因为Customer_Delete存储过程包含以下更新语句: UPDATE [Order] SET [Order]。[Order_Customer_Id] = NULL WHERE([Order]。[Order_Customer_Id] = @Customer_Id)

当然这不起作用,因为Order_Customer_Id列不可为空。 如何指示CodeFluent将值0而不是NULL放入Order_Customer_Id列?

1 个答案:

答案 0 :(得分:1)

CodeFluent并不真正支持不可为空的对象键,因为隐含的语义会有些奇怪。当您从OO角度删除对象时,该对象现在为空,它的标识符不再存在,它不会设置为特定的0或其他值。你可能会在调整这个模型时遇到其他问题。

话虽这么说,改变这种行为的一种方法是使用&#34; persistenceUnlink&#34;涉及的属性的属性,直接在XML文件中。遗憾的是,图形建模器不支持此(古老)属性,并且每次修改模型时都会覆盖它,并使用GUI将其保存回来。

因此,您可以使用custom aspect在您想要的属性上自动应用此属性。下面是这方面的示例代码(注意该方面在启动时运行,因为它实际上基于XML,而不是与大多数方面相反的内存模型):

<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1" defaultNamespace="unlink">
  <cf:pattern name="Unlink Aspect" namespaceUri="http://www.example.com/unlink" preferredPrefix="ul" step="Start">
    <cf:message class="_doc">
       Sample aspect that removes auto unlink in delete procedures
    </cf:message>
    <cf:descriptor name="unlink" targets="Property" defaultValue="true" displayName="Unlink" typeName="boolean" description="Determines if this property will be unlinked during delete" category="Unlink Aspect" />
  </cf:pattern>

  <?code @namespace name="System" ?>
  <?code @namespace name="System.Xml" ?>
  <?code @namespace name="CodeFluent.Model" ?>

<?code
      // use a special utility method to get all elements
      // with the given attribute in a given namespace URI
      var properties  = Project.Package.RootModelPart.SelectElements("unlink", "http://www.example.com/unlink", false);
      foreach(var property in properties)
      {
        // here we set a special attribute not supported by the GUI designer in Visual Studio
        property.SetAttribute("persistenceUnlink", "false");
      }

?>
</cf:project>

你必须做的是:

  • 将此代码保存为文件,例如&#34; unlink.xml&#34;在项目文件周围的某处。
  • 在图形建模器中,右键单击&#34; Aspects&#34; CodeFluent项目的节点,选择&#34;添加现有方面&#34;,浏览到你的unlink.xml文件(它应该显示方面元数据),然后按确定。
  • 返回图形建模器的设计图面,单击要删除持久性链接的属性,转到Visual Studio属性网格,选择蓝色&#34;方面和生产者属性&#34;选项卡,并设置&#34;取消链接&#34;现在应该显示为False(默认为true)。
  • rebuild,存储过程代码不应再包含此关系的链接。