Issue within Dataportal_Update (EditableRoot)

Developer
Jun 14, 2012 at 2:18 AM

Hi Josip,

I'm testing some basic scenarios here, and I'm getting a NullPointerReference exception in DataPortal_Update() because of the following code:

 

if (objectStateManager.TryGetObjectStateEntry(entityKey, out stateEntry))
   data = ctx.ObjectContext.Customers.Single(e => e.CustomerID == this.CustomerID);

The if statement is false so that data is null later down the road.

I simply commented the if statement so that the Customer entity is retrieved anyway, and it worked.

So, my question is what are we trying to validate by the if statement, and why would it fail ? Have you ever got this ?

Thanks

Coordinator
Jun 14, 2012 at 7:22 AM

Hi Luc,

Here's a little bit more code needed for explanation:

if (objectStateManager.TryGetObjectStateEntry(entityKey, out stateEntry))
    data = ctx.ObjectContext.Products.Single(e => e.ProductID == this.ProductID);

if (this.IsSelfDirty)
{	
  if (data == null)
  {
	data = ctx.ObjectContext.Products.CreateObject();
	WriteKeyData(data);
	data.EntityKey = entityKey;
	ctx.ObjectContext.Attach(data);
   }

I did not implement this part of the code but here's how it works:

1. ObjectStateManager checks if the object already exists in the Context

2. If the object is already loaded in the Context then use it

3. If the object is not loaded, then create new object and attach it to the Context (less roundtrips to the DB)

So the object is created if does not exists in the ObjectStateManager, and you should not get Null reference exception.

 

I have changed this behavior in the current version when using DbContext, it's much simpler solution.

 

Regards,

Josip

Developer
Jun 14, 2012 at 1:03 PM
Edited Jun 14, 2012 at 1:04 PM

Josip,

This is not the code that I'm seeing in DataPortal_Update.

Here's what my generated Customer class looks like (Using Northwind database for testing purposes):

[Transactional(TransactionalTypes.TransactionScope)]
override protected void DataPortal_Update()
{
  using (var ctx = Csla.Data.ObjectContextManager .GetManager(CSLAExtensionTest.Data.NorthwindEntitiesDatabase.Name))            	
			{
				
  var objectStateManager = ctx.ObjectContext.ObjectStateManager;
  System.Data.Objects.ObjectStateEntry stateEntry = null;
  System.Data.EntityKey entityKey = GetEntityKey();
  CSLAExtensionTest.Data.Customer data = null;

  if (objectStateManager.TryGetObjectStateEntry(entityKey, out stateEntry))
    data = ctx.ObjectContext.Customers.Single(e => e.CustomerID == this.CustomerID);


  if (this.IsSelfDirty)
  {	
    BeforeUpdate(data);					
    if (Updating != null)
      Updating(this, new DataEventArgs(data));
    WriteNonKeyData(data);
    ctx.ObjectContext.SaveChanges();
					
    LoadEntityKey(data);
    LoadDataToProperties(data);
    AfterUpdate(data);
    if (Updated != null)
      Updated(this, new DataEventArgs(data));

    }

    FieldManager.UpdateChildren();
  }//using
}
partial void BeforeUpdate(CSLAExtensionTest.Data.Customer data);
partial void AfterUpdate(CSLAExtensionTest.Data.Customer data);
internal event EventHandler Updating;
internal event EventHandler Updated;


I'm using the Dev branch of the code.

thx

Coordinator
Jun 14, 2012 at 1:12 PM

Ok, I get it now.

It's a bug introduced with DbContext support. I'll fix that soon.

Until then you can use previous version or use DbContext instead of ObjectContext.

 

~Josip

 

Developer
Jun 14, 2012 at 1:23 PM

Well, I tried that yesterday, but it introduced other errors that got me thinking that I might now be using the proper version of EF.

What version of EF do we support as of now ?

Developer
Jun 14, 2012 at 1:30 PM

Specifically, here is the error I'm getting when switching to DbContext:

Error    2    The type or namespace name 'IDisposable' could not be found (are you missing a using directive or an assembly reference?)    d:\my stuff\documents\visual studio 2010\Projects\CSLAExtensionTest\CSLAExtensionTest\Data\NorthwindEntitiesDatabase.cs    15    40    CSLAExtensionTest

This is caused by a missing "using System;" at the start of file defining DbContextManager

easy fix :)

Coordinator
Jun 14, 2012 at 1:30 PM

All versions. 

Which errors did you get? 

 

 

Developer
Jun 14, 2012 at 1:37 PM

Errrrr......

Actually, I reverted to the Dev version of the CslaExtension.tt file on the tfs server, and I'm getting 26 errors when switch to DbContext:

Error    20    The type 'CSLAExtensionTest.Data.NorthwindEntities' cannot be used as type parameter 'C' in the generic type or method 'CSLAExtensionTest.Data.DbContextManager<C>'. There is no implicit reference conversion from 'CSLAExtensionTest.Data.NorthwindEntities' to 'System.Data.Entity.DbContext'.    d:\my stuff\documents\visual studio 2010\Projects\CSLAExtensionTest\CSLAExtensionTest\Data\Customer.cs    424    38    CSLAExtensionTest

 

Error    21    'System.Data.Objects.ObjectSet<CSLAExtensionTest.Data.Customer>' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type 'System.Data.Objects.ObjectSet<CSLAExtensionTest.Data.Customer>' could be found (are you missing a using directive or an assembly reference?)    d:\my stuff\documents\visual studio 2010\Projects\CSLAExtensionTest\CSLAExtensionTest\Data\Customer.cs    431    33    CSLAExtensionTest

 

Error    24    The type 'CSLAExtensionTest.Data.NorthwindEntities' cannot be used as type parameter 'C' in the generic type or method 'CSLAExtensionTest.Data.DbContextManager<C>'. There is no implicit reference conversion from 'CSLAExtensionTest.Data.NorthwindEntities' to 'System.Data.Entity.DbContext'.    d:\my stuff\documents\visual studio 2010\Projects\CSLAExtensionTest\CSLAExtensionTest\Data\Customer.cs    486    38    CSLAExtensionTest

 

and so on....

Coordinator
Jun 14, 2012 at 1:51 PM

Just to be sure:

1. Installed latest VSIX (1.1.0 ALPHA with DbContext support)?

2. switched EF template to generate DbContext??

3. set CslaUseDbContext property to TRUE?

 

 

 

Developer
Jun 14, 2012 at 2:02 PM

Answers:

 

1) I'm compiling the VSIX from Dev branch, and running it from Visual Studio by launching another instance of Visual Studio with command line arguments "/rootsuffix Exp". This launches a new instance of Visual Studio (in the experimental hive) where the VSIX is automatically installed, so unless the code in the Dev branch differs substantially from the ALPHA release, I should be good

 

2) Not sure where to change this. I seem to remember having to specify a different template file and disabling default output from model, but if you could run that by me once more I'd appreciate. It's been quite a while since I touched EF

 

3) Yes

Coordinator
Jun 14, 2012 at 2:13 PM

2) Right click on the EF designer surface -> Add new code generation item -> DbContext

Developer
Jun 14, 2012 at 2:33 PM

Ok,

I remember now.

But, now I must have my namespaces wrong because the entities generated by the DbContext generation are "fighting" with my CSLA classes. What I mean is that whenever I run the custom tool on my CSLAExtension.tt file, the classes from the context template disapear !!!

I think I'll have to start from scratch.

Developer
Jun 14, 2012 at 3:21 PM

Got it to work now. The reason the files were disappearing is becauseI was generating Each class to its own file, but in the same folder as the DbContext files.

Also, I didn't remember having to name the CSLA classes differently from the Entity classes. If they have the same name, even in different namespaces, you get this exception:

Schema specified is not valid. The mapping of CLR type to EDM type is ambiguous because multiple CLR types match the EDM type 'Customer'.

If I name my CSLA class CSLACustomer, then this goes away. This seems to be a known problem with EF:

http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/5a8ea003-c6bc-4fc6-ad2a-634f09447c49

Cheers