Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Castle ActiveRecord-总是更新子项,为什么?_C#_Database_Activerecord_Transactions_Castle Activerecord - Fatal编程技术网

C# Castle ActiveRecord-总是更新子项,为什么?

C# Castle ActiveRecord-总是更新子项,为什么?,c#,database,activerecord,transactions,castle-activerecord,C#,Database,Activerecord,Transactions,Castle Activerecord,过去的两周是我第一次体验Castle ActiveRecord和ActiveRecord模式。我正在一个经常使用它的大型系统上工作,在我工作的过程中,我发现了一些奇怪的SQL事务问题(如下面的问题)。我将给出一个让我完全困惑的简化版本: 背景: 我有一个ActiveRecord类,我们称之为User 假设这个用户有很多“宠物”对象 [ActiveRecord] 公共类用户:PersistentBase { //... [主密钥] 公共长Id { 得到; 设置 } /// ///对象首次持久化到

过去的两周是我第一次体验Castle ActiveRecord和ActiveRecord模式。我正在一个经常使用它的大型系统上工作,在我工作的过程中,我发现了一些奇怪的SQL事务问题(如下面的问题)。我将给出一个让我完全困惑的简化版本:

背景:

我有一个ActiveRecord类,我们称之为User

假设这个用户有很多“宠物”对象

[ActiveRecord]
公共类用户:PersistentBase
{
//...
[主密钥]
公共长Id
{
得到;
设置
}
/// 
///对象首次持久化到数据库的日期和时间
/// 
[属性,ValidateNonEmpty]
公共日期时间创建日期
{
得到;
设置
}
/// 
///上次将对象持久化到数据库的日期和时间
/// 
[属性,ValidateNonEmpty]
公共日期时间修改日期
{
得到;
设置
}
/// 
///用于乐观并发的属性
/// 
[版本]
公共int锁计数{get;set;}
[HasMany(typeof(Pet),Cascade=ManyRelationCascadeEnum.SaveUpdate,Lazy=false,OrderBy=“Id”)]
公共IList宠物{get;private set;}
//...
保存前受保护的覆盖布尔(IDictionary状态)
{
bool retval=base.BeforeSave(状态);
DateTime now=DateTime.now;
状态[“CreationDate”]=现在;
状态[“修改日期”]=现在;
返回返回;
}
/// 
///在数据库中更新脏对象时调用。使用
///钩住以更新ModificationDate。
/// 
/// 
/// 
/// 
/// 
/// 
受保护的重写bool OnFlushDirty(对象id、IDictionary previousState、IDictionary currentState、IType[]类型)
{
bool retval=base.OnFlushDirty(id、previousState、currentState、类型);
currentState[“ModificationDate”]=DateTime.Now;
返回返回;
}
}
[动态记录]
公共类宠物:PersistentBase
{
[主密钥]
公共长Id
{
得到;
设置
}
/// 
///对象首次持久化到数据库的日期和时间
/// 
[属性,ValidateNonEmpty]
公共日期时间创建日期
{
得到;
设置
}
/// 
///上次将对象持久化到数据库的日期和时间
/// 
[属性,ValidateNonEmpty]
公共日期时间修改日期
{
得到;
设置
}
/// 
///用于乐观并发的属性
/// 
[版本]
公共int锁计数{get;set;}
//...
[属于(“所有者ID”)]
公共用户{get;set;}
//...
保存前受保护的覆盖布尔(IDictionary状态)
{
bool retval=base.BeforeSave(状态);
DateTime now=DateTime.now;
状态[“CreationDate”]=现在;
状态[“修改日期”]=现在;
返回返回;
}
/// 
///在数据库中更新脏对象时调用。使用
///钩住以更新ModificationDate。
/// 
/// 
/// 
/// 
/// 
/// 
受保护的重写bool OnFlushDirty(对象id、IDictionary previousState、IDictionary currentState、IType[]类型)
{
bool retval=base.OnFlushDirty(id、previousState、currentState、类型);
currentState[“ModificationDate”]=DateTime.Now;
返回返回;
}
}
现在,它们都有自动Id字段(由SQLServer2005负责)

问题:

如果我继续向已经有宠物的用户添加一个新宠物并保存该用户,我会看到是否运行SQL分析器,每个宠物都调用了更新。。。但一个也没有改变

我到处抛出断点,发现当我保存用户时,每个宠物都调用了“OnFlushDirty”(同样,尽管它们从未更改)

查看(偶尔修改)这些用户和宠物的外部流程最终会导致严重的事务问题,如果上述场景只插入添加的宠物(而不更新未更改的宠物),则完全可以避免这些问题

问题:

我是否在做一些以上的事情,以确保这种情况不会发生

谢谢你能提供的任何帮助

*编辑1:OnFlushDirty的前一个状态为空。\u值*

编辑:哦!我差点忘了最奇怪的部分

当对这些宠物调用OnFlushDirty时,previousState和currentState存在。。。它们都(作为一个字典)有一个内部变量_值,它应该有以前和当前状态的值

。。。只有CurrentState填充了此变量。previousState的“\u values”变量设置为“null”。请注意,这适用于以前存在的所有宠物。previousState应该总是填充一些内容,对吗

*编辑2:替换自动属性后*

我将自动属性列表替换为具有属性访问器的传统私有成员。这似乎没有什么不同。我在系统上安装了NHProfiler,发现如果我通过IIS运行它,NHProfiler无法连接到我的web应用程序(我在Visual Studio 2008中使用IIS7/Win7)

我想我应该试着改用VisualStudio的“ASP.NET开发服务器”,看看NHProfiler是否会看到这个应用程序

我这样做的时候发生了两件事:

1) NHProfiler看到了我的应用程序并开始收集数据 2) 对孩子们进行的多次更新消失了

但是,切换回IIS7/Win7时,多个更新仍在继续

这是否意味着这可能是某种配置问题?据我所知,,
[ActiveRecord]
public class User: PersistentBase<User>
{
//...
        [PrimaryKey]
    public long Id
    {
        get;
        set;
    }

    /// <summary>
    /// Date and time the object was first persisted to the database
    /// </summary>
    [Property, ValidateNonEmpty]
    public DateTime CreationDate
    {
        get;
        set;
    }

    /// <summary>
    /// Date and time the object was last persisted to the database
    /// </summary>
    [Property, ValidateNonEmpty]
    public DateTime ModificationDate
    {
        get;
        set;
    }
    /// <summary>
    /// Property used for optimistic concurrency
    /// </summary>
    [Version]
    public int LockCount { get; set; }

[HasMany(typeof(Pet), Cascade = ManyRelationCascadeEnum.SaveUpdate, Lazy = false, OrderBy = "Id")]
        public IList<Pet> Pets { get; private set; }

//...

    protected override bool BeforeSave(IDictionary state)
    {
        bool retval = base.BeforeSave(state);
        DateTime now = DateTime.Now;
        state["CreationDate"] = now;
        state["ModificationDate"] = now;
        return retval;
    }

    /// <summary>
    /// Called when a dirty object is going to be updated in the db.  Use this
    /// hook to update ModificationDate.
    /// </summary>
    /// <param name="id"></param>
    /// <param name="previousState"></param>
    /// <param name="currentState"></param>
    /// <param name="types"></param>
    /// <returns></returns>
    protected override bool OnFlushDirty(object id, IDictionary previousState, IDictionary currentState, IType[] types)
    {
        bool retval = base.OnFlushDirty(id, previousState, currentState, types);
        currentState["ModificationDate"] = DateTime.Now;
        return retval;
    }

}

[ActiveRecord]
public class Pet : PersistentBase<Pet>
{

    [PrimaryKey]
    public long Id
    {
        get;
        set;
    }

    /// <summary>
    /// Date and time the object was first persisted to the database
    /// </summary>
    [Property, ValidateNonEmpty]
    public DateTime CreationDate
    {
        get;
        set;
    }

    /// <summary>
    /// Date and time the object was last persisted to the database
    /// </summary>
    [Property, ValidateNonEmpty]
    public DateTime ModificationDate
    {
        get;
        set;
    }
    /// <summary>
    /// Property used for optimistic concurrency
    /// </summary>
    [Version]
    public int LockCount { get; set; }    

//...

[BelongsTo("OwnerId")]
public User User { get; set; }

//...

    protected override bool BeforeSave(IDictionary state)
    {
        bool retval = base.BeforeSave(state);
        DateTime now = DateTime.Now;
        state["CreationDate"] = now;
        state["ModificationDate"] = now;
        return retval;
    }

    /// <summary>
    /// Called when a dirty object is going to be updated in the db.  Use this
    /// hook to update ModificationDate.
    /// </summary>
    /// <param name="id"></param>
    /// <param name="previousState"></param>
    /// <param name="currentState"></param>
    /// <param name="types"></param>
    /// <returns></returns>
    protected override bool OnFlushDirty(object id, IDictionary previousState, IDictionary currentState, IType[] types)
    {
        bool retval = base.OnFlushDirty(id, previousState, currentState, types);
        currentState["ModificationDate"] = DateTime.Now;
        return retval;
    }

}
private IList<Pet> pets = new List<Pet>();