Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# 编辑实体时未经NHibernate本人批准而保存_C#_.net_Nhibernate - Fatal编程技术网

C# 编辑实体时未经NHibernate本人批准而保存

C# 编辑实体时未经NHibernate本人批准而保存,c#,.net,nhibernate,C#,.net,Nhibernate,我有一个测试代码: int productId; { var codersAtWork = productService.Create(); codersAtWork.Title = "Coders At Work"; codersAtWork.Price = new Price(200, 160, 0.25m, "SEK"); codersAtWork.FieldBag.ReleaseDate = new DateTime(2009, 9, 1); p

我有一个测试代码:

int productId;
{
    var codersAtWork = productService.Create();
    codersAtWork.Title = "Coders At Work";
    codersAtWork.Price = new Price(200, 160, 0.25m, "SEK");

    codersAtWork.FieldBag.ReleaseDate = new DateTime(2009, 9, 1);
    productService.Save(codersAtWork);
    productId = codersAtWork.Id;
}

ReSetUp(); // Closes and opens a new session

{
    var codersAtWork = productService.GetById(productId);
    Assert.AreEqual(new DateTime(2009, 9, 1), codersAtWork.FieldBag.ReleaseDate);

    codersAtWork.FieldBag.ReleaseDate = "Tomorrow";
    Assert.Throws<InvalidFieldException>(() => { productService.Save(codersAtWork); });

    var cleanCode = productService.Create();
    cleanCode.Title = "Foo";
    cleanCode.Price = new Price(300, 240, 0.25m, "SEK");
    cleanCode.FieldBag.ReleaseDate = new DateTime(2009, 9, 1);
    productService.Save(cleanCode); // This save will also save my incorrect product.
}

ReSetUp(); // Closes and opens a new session

{
    var codersAtWork = productService.GetById(productId);
    Assert.AreEqual(new DateTime(2009, 9, 1), codersAtWork.FieldBag.ReleaseDate);
}
int-productId;
{
var codersawork=productService.Create();
codersawork.Title=“工作中的编码器”;
Codersawork.Price=新价格(200,160,0.25百万瑞典克朗);
codersawork.FieldBag.ReleaseDate=新的日期时间(2009,9,1);
productService.Save(编码网络);
productId=codersAtWork.Id;
}
ReSetUp();//关闭并打开新会话
{
var codersawork=productService.GetById(productId);
Assert.AreEqual(新日期时间(2009年9月1日),Codersawork.FieldBag.ReleaseDate);
codersawork.FieldBag.ReleaseDate=“明天”;
Assert.Throws(()=>{productService.Save(codersAtWork);});
var cleanCode=productService.Create();
cleanCode.Title=“Foo”;
价格=新价格(300,240,0.25百万瑞典克朗);
cleanCode.FieldBag.ReleaseDate=新日期时间(2009,9,1);
productService.Save(cleanCode);//此保存还将保存我的错误产品。
}
ReSetUp();//关闭并打开新会话
{
var codersawork=productService.GetById(productId);
Assert.AreEqual(新日期时间(2009年9月1日),Codersawork.FieldBag.ReleaseDate);
}
我希望我的服务验证我发送给它的产品,并仅在有效时保存它。但问题是,当我在同一会话中保存其他有效的内容或在会话上调用Flush时,它将被保存,而我无法控制它是否有效。这里的最后一个断言将失败。product.FieldBag.ReleaseDate将为“明天”

FieldBag是动态的,并作为Json保存到数据库中。但这个问题也适用于其他验证


是否可以将NHibernate配置为仅保存我在上显式调用的项。SaveOrUpdate()

您可以调用
Session.execute()
从会话中删除实体。然后NHibernate将忽略对这些实体的更改


或者,您可以使用
无状态会话获取/查询它们

您可以调用
Session.execute()
从会话中删除实体。然后NHibernate将忽略对这些实体的更改


或者,您可以使用
无状态会话获取/查询它们

您可能需要使用事件处理程序来完成此操作。您可以使用PreInsertEventListener和PreUpdateEventListener。检查您的验证,如果验证未能否决该操作,则返回true


您可能需要使用事件处理程序来执行此操作。您可以使用PreInsertEventListener和PreUpdateEventListener。检查您的验证,如果验证未能否决该操作,则返回true


虽然您可以使用
会话.execute()退出对象
,但我建议您查看一下验证方法。如果我理解正确,那么您的
productService.Save
方法将检查传入的对象是否有效。与使用某种类型的服务管理器检查对象是否有效不同,您应该将该验证移到对象本身中,并让对象确保它永远不会变为无效

例如:

class House
{
    public Room Bedroom { get; set; }
}

class HouseService
{
    public ValidateHouse(House aHouse)  //There is no guarantee that this method is ever called
    {
        if (aHouse.Bedroom == null)
        {
            throw new InvalidFieldException();
        }
    }
}
在上面的例子中,您不能保证ValidateHouse曾经被调用过,因此也不能保证您有一个有效的房子要保存(或做任何事情)

将验证移到对象中:

class House
{
    private Room theBedroom;
    public Room Bedroom 
    { 
        get
        {
            return theBedroom;
        }
        set
        {
            if(value == null)
            {
                throw new ArgumentNullException();
            }
            theBedroom = value;
        }
    }
}
在本例中,保证卧室永远不会为空。如果有人试图将null赋值给卧室,则会抛出异常,并且对象永远不会更改。由于对象未更改,NHibernate不会尝试将其持久化。此外,这将使整个应用程序受益,因为您将知道对象始终处于有效状态

house.Bedroom = null;
house.Bedroom.ToString(); //With option 1 this will throw a NullPointerException.

house.Bedroom = null;  //With option 2 this will throw an ArgumentNullException 
                       //but your house object will still be in a known valid state.
house.Bedroom.ToString(); 

虽然您可以使用
Session.execute()
退出对象,但我建议您查看一下验证方法。如果我理解正确,那么您的
productService.Save
方法将检查传入的对象是否有效。与使用某种类型的服务管理器检查对象是否有效不同,您应该将该验证移到对象本身中,并让对象确保它永远不会变为无效

例如:

class House
{
    public Room Bedroom { get; set; }
}

class HouseService
{
    public ValidateHouse(House aHouse)  //There is no guarantee that this method is ever called
    {
        if (aHouse.Bedroom == null)
        {
            throw new InvalidFieldException();
        }
    }
}
在上面的例子中,您不能保证ValidateHouse曾经被调用过,因此也不能保证您有一个有效的房子要保存(或做任何事情)

将验证移到对象中:

class House
{
    private Room theBedroom;
    public Room Bedroom 
    { 
        get
        {
            return theBedroom;
        }
        set
        {
            if(value == null)
            {
                throw new ArgumentNullException();
            }
            theBedroom = value;
        }
    }
}
在本例中,保证卧室永远不会为空。如果有人试图将null赋值给卧室,则会抛出异常,并且对象永远不会更改。由于对象未更改,NHibernate不会尝试将其持久化。此外,这将使整个应用程序受益,因为您将知道对象始终处于有效状态

house.Bedroom = null;
house.Bedroom.ToString(); //With option 1 this will throw a NullPointerException.

house.Bedroom = null;  //With option 2 this will throw an ArgumentNullException 
                       //but your house object will still be in a known valid state.
house.Bedroom.ToString();