Microsoft.SqlServer.Replication.BusinessLogicSupport.BusinessLogicModule. The replication is between a SQL Server 2005 Express subscriber and a SQL Server 2005 publisher/distributer.
The problem is that the resolver class in the DLL will not load; although, it does appear to find the DLL. (If I rename the DLL I get a "file not found error"). The exact error message is:
Microsoft.SqlServer.Replication.ComErrorException
"Error loading custom class "MergeConflictHandler" from custom assembly "MergeConflictHandler",
Error : "Could not load type 'MergeConflictHandler' from assembly 'MergeConflictHandler, Version=1.0.2502.22393, Culture=neutral, PublicKeyToken=0403e50cc4dc27fa'."."}
I placed the DLL in the directory of the program that calls SynchronizationAgent.Synchronize and tried it with and without being registered in the GAC. There was no change. Interestingly, when I move the file out of that location, but register it in the GAC, the file is not found. Thinking it may be a security problem, I gave Everyone Read & Execute and Read privileges. I believe the class is actually instantiated by replmerge.exe, an apparantly unmanaged app, so I tried marking it ComVisible. No Luck.
I registered the resolver with the following T-SQL code:
sp_registercustomresolver @.article_resolver = 'eClinical Notes Conflict Resolver'
, @.is_dotnet_assembly = 'true'
, @.dotnet_assembly_name = 'MergeConflictHandler'
, @.dotnet_class_name = 'MergeConflictHandler'
, @.resolver_clsid = Null
The resolver I've created is not much more than a shell at this point. It is pasted below, but I tried using the code found on MSDN character-for-character and had the same problem.
using System;
using System.Text;
using System.Data;
using System.Data.Common;
using Microsoft.SqlServer.Replication.BusinessLogicSupport;
namespace MergeConflictHandler
{
public class MergeConflictHandler :
Microsoft.SqlServer.Replication.BusinessLogicSupport.BusinessLogicModule
{
// Variables to hold server names.
private string m_PublisherName;
private string m_SubscriberName;
private string m_Artical_Name;
public MergeConflictHandler()
{
}
// Implement the Initialize method to get publication
// and subscription information.
public override void Initialize(string publisher, string subscriber, string distributor, string publisherDB, string subscriberDB,string articleName)
{
m_PublisherName = publisher;
m_SubscriberName = subscriber;
m_Artical_Name = articleName;
}
// Declare what types of row changes, conflicts, or errors to handle.
public override ChangeStates HandledChangeStates
{
get
{
return ChangeStates.UpdateConflicts;
}
}
public override ActionOnUpdateConflict UpdateConflictsHandler(DataSet publisherDataSet, DataSet subscriberDataSet, ref DataSet customDataSet, ref ConflictLogType conflictLogType, ref string customConflictMessage, ref int historyLogLevel, ref string historyLogMessage)
{
if (m_Artical_Name == "PatientAllergies")
{
// Accept the updated data in the Subscriber's data set and apply it to the Publisher.
}
return ActionOnUpdateConflict.AcceptPublisherData;
}
}
}
Does anyone have any thoughts or advice? (Help!)
I had similar problems
I found that the parameter @.dotnet_class_name had to be set to assemblyName.className
If in your case the assembly is named the same as the class then it would need to be set to MergeConflictHandler.MergeConflictHandler
|||
Aero1 Thanks So Much
It is now working, although not exactly as you said. Apparantly the @.dot_class_name parameter needs to be prefixed with the Namespace, not the assemblyName. Perhaps your name space and assemblyName were the same for you? Anyway, I had tried prefixing the Namespace before, but obviously I did something wrong then. As an added benefit, it makes sense. Of course it still should be better documented! So to highlight the answer for future readers:
@.dot_class_name = 'Namespace.Classname'
Thanks again... Life is once again worth living.
This is documented in: http://msdn2.microsoft.com/zh-cn/library/ms147911.aspx
However we will try to make it more discoverable.
No comments:
Post a Comment