What is the optimal way to remove an high number of objects ?

With Session.Remove() is entity data fetched in memory before removal? (probably a dumb question...)

Session.Remove(Query.All<MyEntity>().Where(e => e.ToRemove == true)):

Is there a more optimal way?

ReferentialIntegrityException during Remove

Is this a bug? Or should specify a special OnOwnerRemove action on my EntitySet so that when a "MyEntity" instance is removed all the links from and to this instance are removed too?

[HierarchyRoot]
  public class MyEntity : Entity
  {
    [Field, Key]
    public int Id { get; private set; }

    [Field, Association(PairTo = "Source")]
    public EntitySet<Link> LinksFromThis { get; private set; }

    [Field, Association(PairTo = "Destination")]
    public EntitySet<Link> LinksToThis { get; private set; }
  }

  [HierarchyRoot]
  public class Link : Entity
  {
    [Field, Key]
    public int Id { get; private set; }

    [Field]
    public MyEntity Source { get; set; }

    [Field]
    public MyEntity Destination { get; set; }
  }

using (Session.Open(domain))
      {
        using (var transactionScope = Transaction.Open())
        {
          // Creating new persistent object
          var myEntity1 = new MyEntity();
          var myEntity2 = new MyEntity();

          var link = new Link() { Source = myEntity1, Destination = myEntity2 };

          // Committing transaction
          transactionScope.Complete();
        }
      }

      // Reading all persisted objects from another Session
      using (Session session = Session.Open(domain))
      {
        using (var transactionScope = Transaction.Open())
        {
          session.Remove(Query.All<MyEntity>().Take(1));
          transactionScope.Complete();
        }
      }

Xtensive.Storage.ReferentialIntegrityException was unhandled
  Message=Referential integrity violation on attempt to remove 'TestDoRemove.Model.MyEntity', Key='MyEntity, (1)'.
  Source=Xtensive.Storage
  StackTrace:
       at Xtensive.Storage.ReferentialIntegrity.DenyActionProcessor.Process(RemovalContext context, AssociationInfo association, Entity removingObject, Entity target, Entity referencingObject, Entity referencedObject)
       at Xtensive.Storage.ReferentialIntegrity.RemovalProcessor.ProcessItems(IList`1 entities)
       at Xtensive.Storage.ReferentialIntegrity.RemovalProcessor.Remove(IEnumerable`1 entities)
       at Xtensive.Storage.Session.Remove[T](IEnumerable`1 entities)
       at TestDoRemove.Program.Main(String[] args)

Updated at 17.06.2010 7:58:52

Yes you are right : after a short reflexion I found that my attributes for the EntitySets should be like this:

[HierarchyRoot]
  public class MyEntity : Entity
  {
    [Field, Key]
    public int Id { get; private set; }

    [Field, Association(PairTo = "Source", OnOwnerRemove = OnRemoveAction.Cascade, OnTargetRemove = OnRemoveAction.Clear)]
    public EntitySet<Link> LinksFromThis { get; private set; }

    [Field, Association(PairTo = "Destination", OnOwnerRemove = OnRemoveAction.Cascade, OnTargetRemove = OnRemoveAction.Clear)]
    public EntitySet<Link> LinksToThis { get; private set; }
  }

This works like a charm : many thanks!

PS : maybe the exception message should be more explicit (but I don't know if that's feasible in all cases ;) )

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Jun 16 '10 at 10:41

olorin's gravatar image

olorin
358848792


One Answer:

Alex (Xtensive) wrote:

> Is there a more optimal way?

No, but if you'll study profiler output, you'll see the process utilizes batching. I.e. it is quite fast in comparison to one-by-one removals, although slower then DELETE FROM ... WHERE ... in SQL.

> Is this a bug? Or should specify a special OnOwnerRemove action on my EntitySet so that when a "MyEntity" instance is removed all the links from and to this instance are removed too?

No, this is not a bug. If you'd get similar exception on DB level, it would be a bug.

And yes, in this case you should:

  • Either adjust OnOwnerRemove \ OnTargetRemove actions to enable expected automatic referential integrity fixups

  • Or make necessary fixups manually - i.e. nullify the references pointing to objects you remove / remove the the objects holding these references / set these references to something else / etc.


psulek wrote:

No, but if you'll study profiler output, you'll see the process utilizes batching. I.e. it is quite fast in comparison to one-by-one removals, although slower then DELETE FROM ... WHERE ... in SQL.

Alex, some months ago i make issue with such feature to delete multiple entities in 1 step (...where ID in (...)), am i right? Dont you planned to implement this feature?

answered Jun 17 '10 at 06:32

Editor's gravatar image

Editor
46153156157

> Dont you planned to implement this feature?

We are, but it's definitely not in our near-time plans. Only if someone will really need this ASAP.

(Jun 17 '10 at 06:32) Alex Yakunin Alex%20Yakunin's gravatar image

We are, but it's definitely not in our near-time plans. Only if someone will really need this ASAP.

Ok Alex, i dont really need this for now...

(Jun 17 '10 at 06:32) Peter Ĺ ulek Peter%20%C5%A0ulek's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA