C# Microsoft同步框架与Nhibernate TooManyRowsAffectedexception冲突

C# Microsoft同步框架与Nhibernate TooManyRowsAffectedexception冲突,c#,.net,nhibernate,microsoft-sync-framework,nocount,C#,.net,Nhibernate,Microsoft Sync Framework,Nocount,我们正在尝试将Microsoft Sync框架实现到我们的应用程序中,该应用程序使用NHibernate持久化其域 我们遇到的一个问题是,在Sync框架改变了初始数据库结构(添加了阴影表和触发器)之后,当您尝试将对象插入数据库时,NHibernate似乎会因为抛出ToomAnyRowAffectedException而感到不安 我发现本文提供了在每个update语句周围添加SETNOCOUNT ON和OFF的解决方案,但由于表结构是由nhibernate自动生成的,而同步触发器是由同步框架自动生

我们正在尝试将Microsoft Sync框架实现到我们的应用程序中,该应用程序使用NHibernate持久化其域

我们遇到的一个问题是,在Sync框架改变了初始数据库结构(添加了阴影表和触发器)之后,当您尝试将对象插入数据库时,NHibernate似乎会因为抛出ToomAnyRowAffectedException而感到不安

我发现本文提供了在每个update语句周围添加SETNOCOUNT ON和OFF的解决方案,但由于表结构是由nhibernate自动生成的,而同步触发器是由同步框架自动生成的,因此手动调整所有触发器并不是一个真正的选项

我尝试将sql server 2008属性NOCOUNT设置为on,如此问题中所述: 但这导致StaleStateException(-1行受影响,预期为1行)

你们知道有没有办法配置sync框架来自动设置触发器中的NOCOUNT语句?或者有没有办法告诉NHibernate希望更改的行数更多/更少? 或者你们中的任何人都有一个自动脚本来将这些NOCOUNT语句添加到同步框架的触发器中


提前谢谢

我认为不计较的方法是正确的。可以通过为sync框架使用的所有表设置NOCOUNT来实现这一点。请参阅下面的代码。另一种方法是修补NHibernate并忽略updatecount,请参见()

韩国

保罗

类SqlSyncTriggerHelper
{
private const string triggerSql=@“从sys.triggers、sys.objects中选择sys.triggers.name
其中sys.objects.name={0}和sys.objects.type='U'和sys.triggers.parent\U id=sys.objects.object\U id”;
私有dbsyncopedescription同步范围描述;
公共SqlSyncTriggerHelper(DbSyncScopeDescription syncScopeDescription)
{
this.syncScopeDescription=syncScopeDescription;
}
公共无效应用(SqlConnection conn)
{
SqlTransaction=null;
尝试
{
if(conn.State==System.Data.ConnectionState.Closed)
{
conn.Open();
}
事务=conn.BeginTransaction();
foreach(syncScopeDescription.Tables中的var表)
{
foreach(GetTriggers(table.UnquotedLocalName,conn,transaction)中的字符串触发器)
{
AlterTrigger(触发器、连接、事务);
}
}
Commit();
}
抓住
{
if(事务!=null)
{
transaction.Rollback();
}
投掷;
}
最后
{
if(事务!=null)
{
transaction.Dispose();
}
康涅狄格州关闭();
}
}
私有void AlterTrigger(字符串触发器、SqlConnection连接、SqlTransaction事务)
{
SqlCommand newCmd=newsqlcommand(string.Format(“exec sp_helptext'{0}',触发器”),conn,transaction);
var triggerStringBuilder=新的StringBuilder();
使用(var reader=newCmd.ExecuteReader())
{
while(reader.Read())
{
triggerStringBuilder.Append(reader.GetValue(0)作为字符串);
}
}
var triggerString=triggerStringBuilder.ToString();
triggerString=triggerString.Replace(“创建触发器”、“更改触发器”).Replace(“AS\n”、“AS\nSET NOCOUNT ON\n”)+“\nSET NOCOUNT OFF”;
var alterTriggerCommand=新的SqlCommand(triggerString、conn、事务);
alterTriggerCommand.ExecuteOnQuery();
}
私有IEnumerable GetTriggers(字符串表名、SqlConnection连接、SqlTransaction事务)
{
var resultList=新列表();
var command=newsqlcommand(string.Format(triggerSql,tableName),conn,transaction);
使用(var reader=command.ExecuteReader())
{
while(reader.Read())
{
Add(reader.GetString(0));
}
}
返回结果列表;
}
}
    class SqlSyncTriggerHelper
{
    private const string triggerSql = @"select sys.triggers.name from sys.triggers, sys.objects
        where sys.objects.name='{0}' and sys.objects.type = 'U' and sys.triggers.parent_id = sys.objects.object_id";

    private DbSyncScopeDescription syncScopeDescription;

    public SqlSyncTriggerHelper(DbSyncScopeDescription syncScopeDescription)
    {
        this.syncScopeDescription = syncScopeDescription;
    }

    public void Apply(SqlConnection conn)
    {
        SqlTransaction transaction = null;
        try
        {
            if (conn.State == System.Data.ConnectionState.Closed)
            {
                conn.Open();
            }
            transaction = conn.BeginTransaction();
            foreach (var table in syncScopeDescription.Tables)
            {
                foreach (string trigger in GetTriggers(table.UnquotedLocalName, conn, transaction))
                {
                    AlterTrigger(trigger, conn, transaction);
                }
            }
            transaction.Commit();
        }
        catch
        {
            if (transaction != null)
            {
                transaction.Rollback();
            }
            throw;
        }
        finally
        {
            if (transaction != null)
            {
                transaction.Dispose();
            }
            conn.Close();
        }
    }

    private void AlterTrigger(string trigger, SqlConnection conn, SqlTransaction transaction)
    {
        SqlCommand newCmd = new SqlCommand(string.Format("exec sp_helptext '{0}'", trigger), conn, transaction);
        var triggerStringBuilder = new StringBuilder();
        using (var reader = newCmd.ExecuteReader())
        {
            while (reader.Read())
            {
                triggerStringBuilder.Append(reader.GetValue(0) as string);
            }
        }
        var triggerString = triggerStringBuilder.ToString();
        triggerString = triggerString.Replace("CREATE TRIGGER", "ALTER TRIGGER").Replace(" AS\n", " AS\nSET NOCOUNT ON\n") + "\nSET NOCOUNT OFF";
        var alterTriggerCommand = new SqlCommand(triggerString, conn, transaction);
        alterTriggerCommand.ExecuteNonQuery();
    }

    private IEnumerable<string> GetTriggers(string tableName, SqlConnection conn, SqlTransaction transaction)
    {
        var resultList = new List<string>();
        var command = new SqlCommand(string.Format(triggerSql, tableName), conn, transaction);
        using (var reader = command.ExecuteReader())
        {
            while (reader.Read())
            {
                resultList.Add(reader.GetString(0));
            }
        }
        return resultList;
    }
}