使用会话和延迟加载(working with session and lazy loading)
使用NHibernate和C#,我遇到了删除加载了属性延迟加载的对象的问题。
对象是。
public class Item { public virtual Guid ItemID { get; set; } public virtual string Name { get; set; } public virtual decimal Price { get; set; } public virtual string Image { get; set; } public virtual Iesi.Collections.Generic.ISet<Tax> Taxes { get; set; } }
“Taxes”Collection在这里加载了延迟加载。 所以我需要保持会话开放(据我所知)。 加载“Item”对象时,我使用以下查询。
public Item FindByID(Guid itemID) { //using(var session = NHibernateHelper.OpenSession()) //using (var tr = session.BeginTransaction()) //{ // return session.Get<Item>(itemID); //} var session = NHibernateHelper.OpenSession(); return session.Get<Item>(itemID); }
在上面的
FindByID()
代码中,您可以看到我已经注释掉了一些从数据库中提取对象后关闭会话的代码。 这是因为,我需要打开会话,因为我有Taxes
对象集合可以被访问懒惰。 打开代码部分显示在返回找到的对象后会话仍处于打开状态。当我使用上面加载的对象使用以下代码执行删除时为否。
public void RemoveItem(Item item) { using(var session = NHibernateHelper.OpenSession()) using (var tr = session.BeginTransaction()) { try { session.Delete(item); tr.Commit(); } catch (Exception Ex) { throw Ex; } } }
我收到以下错误..
非法尝试将集合与两个打开的会话相关联
错误很明显,获取的对象已打开会话,当我打开另一个会话以删除同一对象时,会产生此错误。
请有人指导我摆脱这个错误。 谢谢。
Using NHibernate and C#, I am having an issue with deleting an object that is loaded with attribute lazy loading.
The object is.
public class Item { public virtual Guid ItemID { get; set; } public virtual string Name { get; set; } public virtual decimal Price { get; set; } public virtual string Image { get; set; } public virtual Iesi.Collections.Generic.ISet<Tax> Taxes { get; set; } }
The "Taxes" Collection is here loaded with lazy loading. So I need to keep session open(As I learnt). When loading the "Item" object I use the following query.
public Item FindByID(Guid itemID) { //using(var session = NHibernateHelper.OpenSession()) //using (var tr = session.BeginTransaction()) //{ // return session.Get<Item>(itemID); //} var session = NHibernateHelper.OpenSession(); return session.Get<Item>(itemID); }
In the above code for
FindByID()
you can see I have commented out some code that is closing the session once the object is fetched from the DB. It was because, I need the session to be open as I haveTaxes
object collection sould be accessed lazy. The open code section show the session is still open after returning the found object.No when I execute delete using following code with the above loaded object.
public void RemoveItem(Item item) { using(var session = NHibernateHelper.OpenSession()) using (var tr = session.BeginTransaction()) { try { session.Delete(item); tr.Commit(); } catch (Exception Ex) { throw Ex; } } }
I am getting the following error..
Illegal attempt to associate a collection with two open sessions
The error is clear, The fetched object has opened session, when I open another session for deleting the same object, this error is produced.
Please someone guide me to get rid of this error. Thanks.
原文:https://stackoverflow.com/questions/14120300
最满意答案
让父母帮助处理可能需要升级树的任何操作,这些操作包括迭代和删除(包括pop min / max)。
找到下一个祖先(可能是祖父母或更远的祖先)看起来是一个带有或没有父指针的O(log n)操作但是它们不相同,因为大多数节点都在树的底部有一个parent表示在典型情况下只需要一步(并且该步骤已知),而在没有父项的情况下,您必须在大多数情况下降低大部分树。 基本上有一个父指针反转祖先搜索问题。
从实现方面(而不是算法)我也发现插入对于父类更容易 - 我更喜欢为插入和删除实现重新平衡作为迭代循环而不是递归尾调用。
Having a parent helps with any operation that may need to step up the tree, these include both iteration and removal (including pop min/max).
Finding the next ancestor (which may be a grandparent or further) would appear to be an O(log n) operation with or without a parent pointer but they are not the same, given that most nodes are at the bottom of the tree having a parent means that only one step up is required in a typical case (and that step is already known) whereas without a parent you have to step down most of the tree in most cases. Basically having a parent pointer inverts the ancestor search problem.
From an implementation side (rather than algorithm) I also find that insert is easier with a parent - I prefer implementing the rebalance for both insert and remove as an iterative loop rather than recursive tail call.
相关问答
更多-
红黑树Java的空的孩子(Null child in Red-black tree Java)[2023-05-15]
路径25,50 25, 50, --具有1个黑色节点(25); 路径25, 50, 70具有2个黑节点(25和70)。 通常,红黑树的规则不区分叶子和无效儿童; 我们可以说70节点也有两个空子节点,它就是叶子节点。 Path 25, 50, -- has 1 black node (25); path 25, 50, 70 has 2 black nodes (25 and 70). Normally rules for red-black trees don't make a distinction be ... -
步骤在节点Q上进行正确的旋转: 让P = Q的左孩子。 Q的左孩子= P的右孩子 P取代Q作为其父母的孩子 P是对的孩子= Q. 您错过了提供的代码中的粗体步骤。 我认为你的问题是你正在将涉及根节点的轮换视为一种特殊情况。 如果Q是根并且其父级为null显然你不能这样做。 尝试创建一个“头”节点,谁是正确的节点是根。 这允许涉及根的旋转使用常规算法工作。 public static void rotateRight(Node node) { assert(!node.isLeaf() && !nod ...
-
两个最常见的自平衡树算法可能是红黑树和AVL树 。 为了在插入/更新之后平衡树,两种算法都使用旋转的概念,其中树的节点被旋转以执行重新平衡。 在两种算法中,插入/删除操作是O(log n),在Red-Black树的情况下,重新平衡旋转是一个O(1)操作,而使用AVL这是一个O(log n)操作,红黑树在重新平衡阶段的这个方面更有效率,并且是更常用的可能原因之一。 大多数集合库都使用红黑树,包括Java和Microsoft .NET Framework的产品。 Probably the two most co ...
-
如果您对输入数据没有先验知识,则无法知道哪一方更有利于成为新的中间节点或新的子节点。 因此,您可以应用最适合您的规则(最容易编写/计算 - 可能是“总是拿左边的”)。 采用随机方案通常会引入更多不必要的计算。 If you have no prior knowledge about your input data, you cannot know which side is more benefitial of being the new intermediate node or the new child ...
-
更新红黑树中的节点(Update Node in Red Black Tree)[2023-07-09]
如果更改改变了密钥数据,使得节点属于不同的树位置,则是,您需要删除并重新插入节点(您不一定要删除它,因为在空闲节点对象中,但树确实有重新平衡两次 - 一次用于移除,一次用于插入)。 如果更改没有改变节点顺序,那么您只需应用更改,不需要进一步操作。 If the change alters the key data such that the node belongs in a different tree location then yes you need to remove and re-insert ... -
红黑树证明(Red-Black Tree Proof)[2022-06-06]
第一个证明基于其插入算法,这就是为什么总是有一个红色节点。 但是在第二个证明中,你实际上可以构建一个仅由黑色手动构成的红黑树。 使用常用的插入算法,插入时总是会出现红色。 我插入此作为答案,以防有人有同样的问题或知道更准确的单词用作aswer。 阅读材料: http : //www.geeksforgeeks.org/red-black-tree-set-2-insert/ The first prove is based on its insertion algorithm which is why th ... -
首先,只考虑你要做的事情,而不是你如何开始尝试解决它(这是错误的,因为你错误地认为下一个节点总是在正确的子树中,这不是真的)要得到某种树上的迭代器并找到一条记录,然后转到下一步,接下来,直到你到达另一端。 由于二叉树不是一种结构,所以在其他答案中暴露出简单的树: 4 / \ 2 6 / \ / \ 1 3 5 7 假设您必须从节点3转到节点6 。 我将尝试提供一种算法,通过仅考虑我现在使用的节点的特征,允许我从一个节点移动到下一个节点。 节点3的下一个是节点4 ,它要求我们爬上 ...
-
instance Functor (Rbtree c) where fmap = fmap_even where fmap_even _ EmptyTree = EmptyTree fmap_even f (Node x left right) = Node x (fmap_odd f left) (fmap_odd f right) fmap_odd _ EmptyTree = EmptyTree fmap_odd f (Node x left right) ...
-
让父母帮助处理可能需要升级树的任何操作,这些操作包括迭代和删除(包括pop min / max)。 找到下一个祖先(可能是祖父母或更远的祖先)看起来是一个带有或没有父指针的O(log n)操作但是它们不相同,因为大多数节点都在树的底部有一个parent表示在典型情况下只需要一步(并且该步骤已知),而在没有父项的情况下,您必须在大多数情况下降低大部分树。 基本上有一个父指针反转祖先搜索问题。 从实现方面(而不是算法)我也发现插入对于父类更容易 - 我更喜欢为插入和删除实现重新平衡作为迭代循环而不是递归尾调用。 ...
-
谷歌的一些人实际上构建了一个基于B树的C ++标准库容器实现。 它们似乎比标准二叉树实现具有更好的性能。 但是有一个问题。 C ++标准保证从映射或集合中删除元素只会使指向映射或集合中相同元素的其他迭代器无效。 使用基于B树的实现,由于节点拆分和合并,这些新结构上的擦除成员函数可能使对树中其他元素的迭代器无效。 因此,这些实现不是标准实现的完美替代,也不能用于一致的实现。 希望这可以帮助! Some folks over at Google actually built a B-tree based imp ...