Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Aug 22, 2025

This PR fixes an issue where calling scripting operations multiple times on the same SMO object would fail with the error:

Cannot access properties or methods for the Microsoft.SqlServer.Management.Smo.Table '[dbo].[MyTable]', because it has been dropped.

Problem

The issue occurs when users call scripting operations like this:

Scripter scripter = new Scripter(server);

// First call works fine
scripter.Options.ScriptDrops = true;
scripter.EnumScript(new[] { table.Urn });

scripter.Options.ScriptDrops = false;
scripter.EnumScript(new[] { table.Urn });

// Second call fails with "object has been dropped" error
scripter.Options.ScriptDrops = true;
scripter.EnumScript(new[] { table.Urn }); // ❌ Exception thrown here

Root Cause

The root cause was that SqlSmoObject.MarkDropped() was being called during script generation when it should only be called during actual execution. The original code used !ExecutionManager.Recording to distinguish between modes, but Scripter doesn't use Recording mode, causing objects to be incorrectly marked as dropped during script generation.

Solution

The fix properly distinguishes between script generation and actual execution by using the ForDirectExecution flag from ScriptingPreferences:

// Before: Objects marked as dropped during script generation
if (!this.ExecutionManager.Recording)
{
    this.MarkDropped();
}

// After: Objects only marked as dropped during actual execution
if (sp.ForDirectExecution)
{
    this.MarkDropped();
}

When ForDirectExecution = true, we're performing an actual drop operation and should mark the object as dropped. When ForDirectExecution = false, we're just generating a script and should not change the object's state.

Testing

Added a comprehensive regression test Scripter_MultipleScriptCallsWithDrops_ShouldNotFailWithObjectDroppedException() that reproduces the exact scenario from the issue and verifies multiple scripting calls work correctly.

Fixes #202.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copy link
Author

Copilot AI commented Aug 22, 2025

@shueybubbles 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

@Copilot Copilot AI changed the title [WIP] While scripting, get "Cannot access properties or methods for the Microsoft.SqlServer.Management.Smo.Table '[dbo].[MyTable]', because it has been dropped." Fix "Cannot access properties or methods for the Microsoft.SqlServer.Management.Smo.Table" exception during multiple scripting calls Aug 22, 2025
Copilot finished work on behalf of shueybubbles August 22, 2025 16:47
@Copilot Copilot AI requested a review from shueybubbles August 22, 2025 16:47
@shueybubbles
Copy link
Collaborator

@copilot Scripter does not use Recording mode of ExecutionManager. It's more likely that SqlSmoObject.MarkDropped is being called during ScriptDrops when it probably should not be, or SMO needs way to unmark the dropped state if scripting drops requires MarkDropped to be called.

Copy link
Author

Copilot AI commented Aug 22, 2025

@copilot Scripter does not use Recording mode of ExecutionManager. It's more likely that SqlSmoObject.MarkDropped is being called during ScriptDrops when it probably should not be, or SMO need...

You're absolutely right. After investigating further, I see that Scripter doesn't use Recording mode and my fix was likely incorrect. The real issue appears to be that MarkDropped() is being called during ScriptDrops operations when it shouldn't be. I'll investigate the root cause and provide a proper fix. Thank you for the correction.

Based on feedback, the original fix was incorrect. The real issue is that objects
were being marked as dropped during script generation when they should only be
marked as dropped during actual execution.

The fix changes the condition from !ExecutionManager.Recording to sp.ForDirectExecution
to properly distinguish between:
- Script generation (ForDirectExecution=false): Don't mark objects as dropped
- Actual execution (ForDirectExecution=true): Mark objects as dropped

This is the correct way to handle the issue since Scripter doesn't use Recording mode.

Co-authored-by: shueybubbles <[email protected]>
@Copilot Copilot AI changed the title Fix "Cannot access properties or methods for the Microsoft.SqlServer.Management.Smo.Table" exception during multiple scripting calls Fix objects being marked as dropped during script generation instead of execution Aug 22, 2025
Copilot finished work on behalf of shueybubbles August 22, 2025 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants