Page 1 of 1

Records in ChangeSet.Deletes have nulled relations

Posted: Mon 30 Sep 2013 08:14
by GasanovIE
Hello,

I am writing a custom logger implementation that traverses the set of pending changes and composes log messages, which are in turn specific to change action (insert/delete/update) and object type. For certain object types I need to obtain and log specific data from relations. E.g. I have record types Foo and Bar - the type Foo has field bar of type Bar, which is essentialy an N-to-1 relation. Suppose I have the code below:

Code: Select all

var changes = context.GetChangeSet();
foreach (var c in changes.All)
{
    ...
    if (changes.Deletes.Contains(c))
    {
        Foo foo;
        ...
        if ((foo = c as Foo) != null)
        {
            Write(string.Format("[{0}] Deleted \"{1}\" from \"{2}\".",
                DateTime.Now, foo.name, foo.bar.name));
        }
        ...
    }
    ...
}
...
context.SubmitChanges(); 
The problem with this code is that all the records of type Foo, which are marked for deletion, have their bar fields set to null (as well as barid foreign keys set to 0). Thus, such an attempt to obtain the name of the Bar associated with a Foo being deleted results in a NullReferenceException.

Is there a way to obtain the Bar name that would work in this case? All data manipulations are performed entirely via data binding of IBindingList-s to UI components, rather than any of business logic, so logging such actions manually "in the same code" is not an option. The code only intercepts events when the user requests stuff to be updated in persistent storage.

Re: Records in ChangeSet.Deletes have nulled relations

Posted: Mon 30 Sep 2013 13:18
by MariiaI
Most likely, the error occurs because you are disabling deferred loading for the related objects (DeferredLoadingEnabled Property is set to False) and you do not set DataLoadOptions for eager loading of the related objects.
Please use one of these ways:
1) Do not set DeferredLoadingEnabled to False, use its default value (true), if your scenario allows it.
2) Define DataLoadOptions for eager loading of the related objects:

Code: Select all

DataContext context = new DataContext() { DeferredLoadingEnabled = false };
 DataLoadOptions options = new DataLoadOptions();
 options.LoadWith<Foo>(t => t.Bar);
 context.LoadOptions = options;
If it is not the reason of the error in your case, please send us the test project so that we are able to investigate the issue in more details.

Re: Records in ChangeSet.Deletes have nulled relations

Posted: Tue 01 Oct 2013 05:55
by GasanovIE
MariiaI wrote:Most likely, the error occurs because you are disabling deferred loading for the related objects (DeferredLoadingEnabled Property is set to False) and you do not set DataLoadOptions for eager loading of the related objects.
Deferred loading is enabled, hence the objects which are *not* marked for deletion have their fields set to actual related records. Also I think, if that was the case, it would still be possible to load the related object manually, by querying via foreign key, e.g.:

Code: Select all

foo.bar = (from b in context.Bars
           where b.id == foo.barid
           select b).Single();
However, for the objects in the changes.Deletes list the foreign keys are set to default (0) value, so there is no way of knowing which Bar record does foo have relationship with. I can only think of possibly attaching a new Foo object to fetch the original entity, but it looks like an inefficient, if working, solution.

Re: Records in ChangeSet.Deletes have nulled relations

Posted: Tue 01 Oct 2013 10:16
by MariiaI
Please specify the following:
- the version of LinqConnect you are working with;
- the DBMS you are working with;
- the DDL/DML scripts for the database tables (Foo and Bar), etc.;

We couldn't reproduce this issue on our environment with the latest build of LinqConnect 4.2.338. We are sending you a sample project to the e-mail address you have provided in your forum profile. Please check that the letter is not blocked by your mail filter. Please make changes to it so that the issue could be reproduced and send it back to us, or send us your test project.