默认持久性强制设置为 true 无论如何都会删除关联 table 的行
Default persistence enforce set to true would anyway delete association table's lines
属性 defaultPersistenceEnforce 在项目级别设置为 true。我们考虑以下示例。
Meeting ----*> Contact <---- Case
当我们在 table Case
中引用了一个联系人时,存储过程 Contact_Delete()
的调用将如预期的那样失败。
但是当tableCase
中没有引用时,执行存储过程Contact_Delete()
会删除关联tableMeeting_Contacts_Contact
.[=中的行20=]
这没有多大意义,因为我想阻止这种行为。特别是,我没有为删除指定任何级联关系。
我想确保元组不会在这样的 table 中被删除,尤其是在被引用时。
我怎样才能让存储过程 Contact_Delete()
只删除联系人而不考虑引用?
感谢您的回答,
附上模型部分和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
这是设计使然。为实体生成的 delete
过程也会删除 多对多 table.
的记录
一个简单的解决方法是创建一个 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
属性 defaultPersistenceEnforce 在项目级别设置为 true。我们考虑以下示例。
Meeting ----*> Contact <---- Case
当我们在 table Case
中引用了一个联系人时,存储过程 Contact_Delete()
的调用将如预期的那样失败。
但是当tableCase
中没有引用时,执行存储过程Contact_Delete()
会删除关联tableMeeting_Contacts_Contact
.[=中的行20=]
这没有多大意义,因为我想阻止这种行为。特别是,我没有为删除指定任何级联关系。
我想确保元组不会在这样的 table 中被删除,尤其是在被引用时。
我怎样才能让存储过程 Contact_Delete()
只删除联系人而不考虑引用?
感谢您的回答,
附上模型部分和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
这是设计使然。为实体生成的 delete
过程也会删除 多对多 table.
一个简单的解决方法是创建一个 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