Sladescross's Blog

Blogging about Sharepoint related stuff

Change Data Capture June 24, 2013

Filed under: .NET,Change Data Capture,LSN — sladescross @ 3:04 pm

The source of change data for change data capture is the SQL Server transaction log. As inserts, updates, and deletes are applied to tracked source tables, entries that describe those changes are added to the log. The log serves as input to the capture process. This reads the log and adds information about changes to the tracked table’s associated change table. Functions are provided to enumerate the changes that appear in the change tables over a specified range, returning the information in the form of a filtered result set. The filtered result set is typically used by an application process to update a representation of the source in some external environment.


Returns one net change row for each source row changed within the specified LSN range. That is, when a source row has multiple changes during the LSN range, a single row that reflects the final content of the row is returned by the function. For example, if a transaction inserts a row in the source table and a subsequent transaction within the LSN range updates one or more columns in that row, the function returns only one row, which includes the updated column values.

This enumeration function is created when a source table is enabled for change data capture and net tracking is specified. To enable net tracking, the source table must have a primary key or unique index. The function name is derived and uses the format cdc.fn_cdc_get_net_changes_capture_instance, where capture_instance is the value specified for the capture instance when the source table was enabled for change data capture. For more information, see sys.sp_cdc_enable_table (Transact-SQL).

Returns one row for each change applied to the source table within the specified log sequence number (LSN) range. If a source row had multiple changes during the interval, each change is represented in the returned result set. In addition to returning the change data, four metadata columns provide the information you need to apply the changes to another data source. Row filtering options govern the content of the metadata columns as well as the rows returned in the result set. When the ‘all’ row filter option is specified, each change has exactly one row to identify the change. When the ‘all update old’ option is specified, update operations are represented as two rows: one containing the values of the captured columns before the update and another containing the values of the captured columns after the update.

::= { all | all update old }
An option that governs the content of the metadata columns as well as the rows returned in the result set.

Can be one of the following options:
Returns all changes within the specified LSN range. For changes due to an update operation, this option only returns the row containing the new values after the update is applied.
all update old
Returns all changes within the specified LSN range. For changes due to an update operation, this option returns both the row containing the column values before the update and the row containing the column values after the update.


Sharepoint 2010 Disabling List View Threshold April 25, 2010

Filed under: .NET,List View Threshold — sladescross @ 3:59 pm


PDB Files March 12, 2010

Filed under: .NET,Debugging,PDB,Symbols — sladescross @ 12:14 am

As John Cunningham, the development manager for all things diagnostics on Visual Studio, said at the 2008 PDC, “Love, hold, and protect your PDBs.” At a minimum, every development shop must set up a Symbol Server. I’ve written about Symbol Servers in MSDN Magazine and more extensively in my book, Debugging .NET 2.0 Applications. You can also read the Symbol Server documentation itself in the Debugging Tools for Windows help file. Look at those resources to learn more about the details. Briefly, a Symbol Server stores the PDBs and binaries for all your public builds. That way no matter what build someone reports a crash or problem, you have the exact matching PDB file for that public build the debugger can access. Both Visual Studio and WinDBG know how to access Symbol Servers and if the binary is from a public build, the debugger will get the matching PDB file automatically.

On the other machine, what I’ve seen numerous developers do after using GACUTIL to put the assembly into the GAC is to open up a command window and dig around in C:\WINDOWS\ASSEMBLY\ to look for the physical location of the assembly on disk. While it is subject to change in the future, an assembly compiled for Any CPU is actually in a directory like the following:


Example is the name of the assembly, is the version number, and 682bc775ff82796a is the public key token value. Once you’ve deduced the actual directory, you can copy the PDB file to that directory and the debugger will load it.

If you’re feeling a little queasy right now about digging through the GAC like this, you should, as it is unsupported and fragile. There’s a better way that seems like almost no one knows about, DEVPATH. The idea is that you can set a couple of settings in .NET and it will add a directory you specify to the GAC so you just need to toss the assembly and it’s PDB file into that directory so debugging is far easier. Only set up DEVPATH on development machines because any files stored in the specified directory are not version checked as they are in the real GAC.


Class Master March 10, 2010

Filed under: .NET,Tool — sladescross @ 9:25 pm


Non-Compliant CLS Types In Powershell March 1, 2010

Filed under: .NET,CLS,Non-Compliant,Overloading,Powershell — sladescross @ 3:49 pm

One of the rules of a so-called “CLS compliant type” (cls = common lanaguage specification) is that you should not expose any public members that only differ in casing. The SPContentDatabase type has two properties, “Id” and “ID.” This is perfectly legal in C# since case in important in that language and the compiler sees them as different as chalk and cheese. However, in VB.NET, case is not important and as such it [vb] has no native mechanism to differentiate between the two. The same goes for PowerShell’s grammar. So, how do we get around this?

First, you grab a handle to the method directly by asking for it from the Type itself:

PS> $idMethod1 = [Microsoft.SharePoint.Administration.SPContentDatabase].getmethod(“get_ID”)

and for the second version,

PS> $idMethod2 = [Microsoft.SharePoint.Administration.SPContentDatabase].getmethod(“get_Id”)

Note the differing case for get_Id and get_ID. Btw, Properties like ID in .NET are actually served by special accessor methods prefixed with get_ and set_, hence the prefixes. Next, you need a way to invoke those methods on the instance itself: this is done by using the Invoke method on the MethodInfo object representing the method itself. You pass the instance to the Invoke method telling it that the method is “instance” (e.g. not static/shared) and “public” and it will call that method for you on the instance, returning the value, if any.

PS> $result = $idMethod1.Invoke($site.ContentDatabase, “instance,public”, $null, $null, $null)

Call overloaded non-compliant method in Powershell. GetChanges.

function Display_ChangeTokens_For_ContentDatabase([string] $ServerName, [string] $SiteCollectionName, [string] $ChangeCSVFile)

 $spsite = new-object Microsoft.Sharepoint.SPSite($ServerName + $SiteCollectionName);

 $spcontentdatabaseidmethod =  [Microsoft.SharePoint.Administration.SPContentDatabase].getmethod(“get_ID”);
 $spcontentdatabaseguid = $spcontentdatabaseidmethod.Invoke($spsite.ContentDatabase, “instance,public”, $null, $null, $null);

 $spcontentdatabaseguid.ToString() | select;

 $spcontentdatabasemethods = [Microsoft.SharePoint.Administration.SPContentDatabase].GetMethods(“instance,public”);

 $spcontentdatabasemethods | foreach-object {

  if ($ -eq “GetChanges”)

   $parameters = @($_.GetParameters())

   # Call Overloaded GetChanges Without Parameters

   if($parameters.Count -eq 0)

    $spcontentdatabasechanges = $_.Invoke($spsite.ContentDatabase, “instance,public”, $null, $null, $null);
    #$spcontentdatabasechanges | select;

    $spcontentdatabasechanges | foreach-object {

     #$spcontentdatabasechanges.Id + ” ” + ” ” + $spcontentdatabasechanges.ChangeType + ” ” + $spcontentdatabasechanges.SiteId + ” ” + $spcontentdatabasechanges.Time.ToString() + ” ” + $spcontentdatabasechanges.ChangeToken.ToString() | add-content -encoding ascii  $ChangeCSVFile;
     $spcontentdatabasechanges.Id | add-content -encoding ascii  $ChangeCSVFile;


 # Dispose of Site


and to get all the changes back use this.

function Send_ChangeTokens_All__For_ContentDatabase([string] $ServerName, [string] $SiteCollectionName, [string] $ChangeCSVFile)

 $spsite = new-object Microsoft.Sharepoint.SPSite($ServerName + $SiteCollectionName);

 $spcontentdatabaseidmethod =  [Microsoft.SharePoint.Administration.SPContentDatabase].getmethod(“get_ID”);
 $spcontentdatabaseguid = $spcontentdatabaseidmethod.Invoke($spsite.ContentDatabase, “instance,public”, $null, $null, $null);

 “Content Database is ” + $spcontentdatabaseguid.ToString() | select;

 $spcontentdatabasegetchangesmethod =  [Microsoft.SharePoint.Administration.SPContentDatabase].getmethod(“GetChanges”,[Microsoft.SharePoint.SPChangeToken]);
 $targetparameters = @($null);
 $total = 0;


  $spcontentdatabasechanges = $spcontentdatabasegetchangesmethod.Invoke($spsite.ContentDatabase, “instance,public”, $null, $targetparameters, $null);
  $total += $spcontentdatabasechanges.Count;

  $spcontentdatabasechanges | foreach-object {

    $_.ChangeToken.ToString() + ” ” + $_.ChangeType.ToString() + ” ” + $_.SiteId.ToString() + ” ” + $_.Time.ToString()  | add-content -encoding ascii  $ChangeCSVFile;


  $targetparameters[0] = $spcontentdatabasechanges.LastChangeToken;

  if($targetparameters[0] -ne $null) { 
   “Change Token ” + $targetparameters[0].ToString() | select; }

 } while ($spcontentdatabasechanges.Count -gt 0)

 “Total ” + $total | select;

 # Dispose of Site


Notice that the “Invoke” is different in the PS and the C#. Also notice how convoluted the PS is when trying to do a simple object.GetType() , but i guess PS wasnt meant for this sort of thing anyway, so we cant complain.

Powershell for Reflection.


net command February 15, 2010

Filed under: .NET,Tool — sladescross @ 3:38 pm

net view \\hope

View the available computers and their shared resources you may use either of the below commands. The first example displays available computers. The last command would display the shared resources on the hope computer.

net use z: \\computer\folder

Map the Z: drive to the network path //computer/folder.


Exception In Constructor February 1, 2010

Filed under: .NET,Constructor,Exception — sladescross @ 11:26 pm


Fusion Logging January 29, 2010

Filed under: .NET,Fusion,Logging,Timer — sladescross @ 12:34 pm

For BadImageFormatException:
Try running peverify.exe on the file. That will give a more specific description about why it s considered a bad image. Keep in mind that modules built against v2 can not be loaded by a pre-v2 CLR.

For SecurityException:
You need Execute permission for loading any assembly. Also, if a codebase was used to load this file, you would need both FileIOPermission.Read and FileIOPermission.PathDiscovery or else WebPermission to the location (depending on whether this is a local file or a URL). Try caspol.exe to check your managed security settings.

For FileLoadException:

For an “Access is denied” message (for hresult E_ACCESSDENIED, 0×80070005):
Run tlist -m on the file to see if another process has the file locked and without share-read access. If not, check the ACLs for the file and its dependencies (especially if you’re using impersonation).

For a “The located assembly’s manifest definition with name [yourAssembly] does not match the assembly reference” message (for hresult FUSION_E_REF_DEF_MISMATCH, 0×80131040):
The Fusion log will say which part of the assembly reference failed to match what was found. It will be the assembly name, culture, public key (or token) or version (if the found assembly was strongly-named).

For “Unverifiable image [yourAssembly] can not be run” or “Can not run executable [yourAssembly] because it contains relocations” messages (for hresult COR_E_FIXUPSINEXE, 0×80131019):
That image must be run as the process exe or else be compiled as a dll. This is because MC++ has made optimizations for you in your image, based on the assumption that it will be the process exe. If it’s not the process exe, it won t be loaded at the expected location, so the assumed offsets will be incorrect. When the CLR sees such a file loaded as a non-process exe, it will reject the load.



.NET Assembly Version and Assembly File Version December 30, 2009

Filed under: .NET,Assembly,Versioning — sladescross @ 3:28 pm


.NET Naming Standards December 27, 2009

Filed under: .NET,Naming Standards — sladescross @ 3:56 pm—best-practices.aspx

Standard Based Upon Microsoft .NET Library Standards
Pascal Case, no underscores. Try to avoid abbreviations. Members must differ by more than case to be usable from case-insensitive languages like Visual Basic .NET.
Why: This convention is consistent with the .NET Framework and is easy to read.



Get every new post delivered to your Inbox.

Join 63 other followers