0

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

这是我的模型:

<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 插入列“Order_Customer_Id”,表“CodeFluentTest.dbo.Order”;列不允许空值。更新失败。

这是因为 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 列?

4

1 回答 1

1

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

话虽如此,改变这种行为的一种方法是persistenceUnlink直接在 XML 文件中使用相关属性的“”属性。不幸的是,图形建模器不支持这个(古老的)属性,并且每次您修改模型并使用 GUI 将其保存回来时都会覆盖它。

因此,您可以做的是使用自定义方面自动将此属性应用于您想要的属性。以下是此类方面的示例代码(请注意,方面在启动时运行,因为它确实基于 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>

你必须做的是:

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