0

プロパティ defaultPersistenceEnforce は、プロジェクト レベルで true に設定されます。次の例を検討します。

Meeting ----*> Contact <---- Case

テーブルCaseで参照されている連絡先が 1 つある場合、ストアド プロシージャの呼び出しはContact_Delete()期待どおりに失敗します。

ただし、テーブルCaseに参照がない場合、ストアド プロシージャを実行Contact_Delete()すると、関連付けテーブル内の行が削除されますMeeting_Contacts_Contact

そのような振る舞いを防ぎたいので、あまり意味がありません。特に、削除のカスケード関係は指定しませんでした。

特に参照されている場合、そのようなテーブルでタプルが消去されていないことを確認したいと思います。Contact_Delete()Contact のみを削除し、参照を考慮しないストアド プロシージャを使用するにはどうすればよいですか?

ご回答有難うございます、

モデル パーツと Contact_Delete ストアド プロシージャの定義を同封しました。

<cf:project defaultNamespace="WcfServices.Model" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" xmlns:cfx="http://www.softfluent.com/codefluent/modeler/2008/1" xmlns:cfps="http://www.softfluent.com/codefluent/producers.sqlserver/2005/1" xmlns:cfom="http://www.softfluent.com/codefluent/producers.model/2005/1" xmlns:cfsps="http://www.softfluent.com/codefluent/producers.sqlpivotscript/2013/1" defaultPersistenceEnforce="true" createDefaultMethodForms="true" createDefaultApplication="false" createDefaultHints="false">
  <cf:import path="Default.Surface.cfp" />
  <cf:producer name="SQL Server" typeName="CodeFluent.Producers.SqlServer.SqlServerProducer, CodeFluent.Producers.SqlServer">
    <cf:configuration produceViews="true" targetDirectory="..\WcfServices.persistence" cfx:targetProject="..\WcfServices.persistence\WcfServices.persistence.sqlproj" cfx:targetProjectLayout="Update, DontRemove" />
  </cf:producer>
  <cf:producer name="Business Object Model (BOM)" typeName="CodeFluent.Producers.CodeDom.CodeDomProducer, CodeFluent.Producers.CodeDom">
    <cf:configuration compileWithVisualStudio="true" compile="false" codeDomProviderTypeName="CSharp" targetDirectory="..\WcfServices.model" cfx:targetProject="..\WcfServices.model\WcfServices.model.csproj" cfx:targetProjectLayout="Update">
      <subProducer typeName="Ixcys.Producers.ServiceModelProducer.ServiceProducer, Ixcys.Producers.ServiceModelProducer, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" compileWithVisualStudio="true" compile="false" codeDomProviderTypeName="CSharp" targetDirectory="..\WcfServices.proxy" silverlightTargetVersion="Unspecified" jsonOptions="EnableJson" cfx:targetProject="..\WcfServices.web\WcfServices.web.csproj" cfx:targetProjectLayout="Update" />
    </cf:configuration>
  </cf:producer>
  <cf:producer name="SQL Server Pivot Script" typeName="CodeFluent.Producers.SqlServer.SqlPivotScriptProducer, CodeFluent.Producers.SqlServer">
    <cf:configuration targetDirectory="..\WcfServices.web" cfx:targetProject="..\WcfServices.web\WcfServices.web.csproj" cfx:targetProjectLayout="Update" />
  </cf:producer>
  <cf:entity name="Contact" namespace="Example.Model.Contact" categoryPath="/WcfServices.Model">
    <cf:property name="ContactId" key="true" persistenceEnforce="true" />
    <cf:property name="Name" persistenceEnforce="true" />
  </cf:entity>
  <cf:entity name="Case" namespace="Example.Model.Contact" categoryPath="/WcfServices.Model">
    <cf:property name="CaseId" key="true" persistenceEnforce="true" />
    <cf:property name="Description" persistenceEnforce="true" />
    <cf:property name="InChargeContact" typeName="Example.Model.Contact.Contact" persistenceEnforce="true" />
  </cf:entity>
  <cf:entity name="Meeting" namespace="Example.Model.Contact" categoryPath="/WcfServices.Model">
    <cf:property name="MeetingId" key="true" persistenceEnforce="true" />
    <cf:property name="Date" typeName="date" persistenceEnforce="true" />
    <cf:property name="Label" persistenceEnforce="true" />
    <cf:property name="Contacts" typeName="Example.Model.Contact.ContactCollection" persistenceEnforce="true" />
  </cf:entity>
</cf:project>

ストアド プロシージャ Contact_Delete

CREATE PROCEDURE [dbo].[Contact_Delete]
(
 @Contact_ContactId [uniqueidentifier],
 @_rowVersion [rowversion]
)
AS
SET NOCOUNT ON
DECLARE @error int, @rowcount int
DECLARE @tran bit; SELECT @tran = 0
IF @@TRANCOUNT = 0
BEGIN
 SELECT @tran = 1
 BEGIN TRANSACTION
END
DELETE FROM [Meeting_Contacts_Contact]
    WHERE ([Meeting_Contacts_Contact].[Contact_ContactId] = @Contact_ContactId)
SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT
DELETE FROM [Contact]
    WHERE (([Contact].[Contact_ContactId] = @Contact_ContactId) AND ([Contact].[_rowVersion] = @_rowVersion))
SELECT @error = @@ERROR, @rowcount = @@ROWCOUNT
IF(@rowcount = 0)
BEGIN
    IF @tran = 1 ROLLBACK TRANSACTION
    RAISERROR (50001, 16, 1, 'Contact_Delete')
    RETURN
END
IF @tran = 1 COMMIT TRANSACTION

RETURN
GO
4

1 に答える 1

1

これは仕様によるものです。deleteエンティティに対して生成されたプロシージャは、多対多テーブルのレコードも削除します

簡単な回避策は、CFQLメソッドを作成することDeleteByIdです:

DELETE(Id) WHERE Id = @Id

このメソッドは、次のストアド プロシージャを生成します。

CREATE PROCEDURE [dbo].[Meeting_DeleteById]
(
 @Id [uniqueidentifier]
)
AS
SET NOCOUNT ON
DECLARE @deletedcount int
DELETE FROM [Meeting]
    WHERE ([Meeting].[Meeting_Id] = @Id)
SELECT @deletedcount = @@ROWCOUNT

SELECT @deletedcount 
RETURN
GO
于 2016-09-08T15:26:29.380 に答える