New Posts New Posts RSS Feed: Value is not compatible with property
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Value is not compatible with property

 Post Reply Post Reply
Author
bennage View Drop Down
Newbie
Newbie
Avatar

Joined: 04-Aug-2010
Location: Tallahassee, FL
Posts: 9
Post Options Post Options   Quote bennage Quote  Post ReplyReply Direct Link To This Post Topic: Value is not compatible with property
    Posted: 04-Aug-2010 at 9:00am
I have 3 entities of interest. Something like this:
Order
LineItem
Product

Order can have many LineItems, a LineItem can have a single Product.
Everything has integer ids.

I retrieve an instance of an existing Order.
I create a new LineItem and associate it with an existing Product.
I then add the new LineItem to a collection of LineItems on the Order instance. I get the exception below.
The exception occurs as a add the LineItem. For example, on:
order.LineItems.Add( new LineItem() { Product = product };

Prior to adding , the LineItem has an id of -100 (or -101 or something similar).

Value is not compatible with property: Id DataType: System.Int32
   at IdeaBlade.EntityModel.EntityWrapper.CheckPropertyValueCompatibility(DataEntityProperty property, Object newValue)
   at IdeaBlade.EntityModel.EntityWrapper.SetValueWithChangeNotification(DataEntityProperty property, Object newValue)
   at IdeaBlade.EntityModel.EntityWrapper.SetValue(DataEntityProperty targetProperty, EntityWrapper sourceEntity, DataEntityProperty sourceProperty)
   at IdeaBlade.EntityModel.ScalarEntityReference`1.UpdateOtherProperties(EntityRelationLink relationLink, EntityWrapper fromEntity, EntityWrapper toEntity)
   at IdeaBlade.EntityModel.ScalarEntityReference`1.UpdateFkForNewToEntity(EntityWrapper toEntity)
   at IdeaBlade.EntityModel.ScalarEntityReference`1.SetEntity(T newValue, Boolean updateFkValues, Boolean updateInverseValues)
   at IdeaBlade.EntityModel.ScalarEntityReference`1.AddEntity(Object entity, Boolean updateInverseValues)
   at IdeaBlade.EntityModel.RelatedEntityList`1.AddInverse(T otherEntity)
   at IdeaBlade.EntityModel.RelatedEntityList`1.AddOrInsert(Int32 index, T item, Boolean updateInverse)
   at IdeaBlade.EntityModel.RelatedEntityList`1.Add(T item)
   at MSU.CollegeOfMusic.MVC.Controllers.AdmissionApplicationController.AddInstitution(InstitutionOfInterestViewModel vm, Int32 applicationId) in E:\projects\msu\src\MSU.CollegeOfMusic.MVC\Controllers\AdmissionApplicationController.cs:line 75
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a()
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
Back to Top
bennage View Drop Down
Newbie
Newbie
Avatar

Joined: 04-Aug-2010
Location: Tallahassee, FL
Posts: 9
Post Options Post Options   Quote bennage Quote  Post ReplyReply Direct Link To This Post Posted: 04-Aug-2010 at 10:41am
I should add, this is 6.0.4, in the context of an ASP.NET MVC application.
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post Posted: 04-Aug-2010 at 11:47am
Hi Christoper -
 
Hmm ... that sure is raw
 
  order.LineItems.Add( new LineItem() { Product = product };
I'm sure this is demo code :-)
 
I don't know the answer because I don't have the code. But 'm going to interpret the call stack with you and see if that is suggestive.
 
It seems you survived the creation of the LineItem and the assignment of its Product.
 
DevForce is in the process of adding the line item to the list. Having realized the direction of the relationship, it knows it must update the Order FK value of the LineItem
 
  ...AddInverse(T otherEntity)
  ...SetEntity(T newValue, Boolean updateFkValues, Boolean updateInverseValues)

Now it must ensure that the Order FK property type (LineItem.OrderId ?) is compatible with the type of the Order' primary key type (Order.Id).
 
  ...CheckPropertyValueCompatibility(DataEntityProperty property, Object newValue)
 
And apparently the two property types are "incompatible"
 
   Value is not compatible with property: Id DataType: System.Int32
 
This makes me wonder if the Order.Id and LineItem.OrderId are both Int32. Maybe they are both integer types but not both Int32. Of course then I'd have to wonder (a) how you got this far without DevForce objecting earlier and (b) why we don't coerce if we can. But let's see what you find out first.
Back to Top
bennage View Drop Down
Newbie
Newbie
Avatar

Joined: 04-Aug-2010
Location: Tallahassee, FL
Posts: 9
Post Options Post Options   Quote bennage Quote  Post ReplyReply Direct Link To This Post Posted: 04-Aug-2010 at 12:18pm
It turns out the "Value is not compatible with property" was something of a red herring.
My problem was that I was trying to load an Order that didn't exist (id = 0). When I corrected this (so that I was actually loading a real order) this particular error when away.
I'm now experiencing another exception. I'll report back once it is fixed.
Back to Top
bennage View Drop Down
Newbie
Newbie
Avatar

Joined: 04-Aug-2010
Location: Tallahassee, FL
Posts: 9
Post Options Post Options   Quote bennage Quote  Post ReplyReply Direct Link To This Post Posted: 04-Aug-2010 at 12:41pm
Ok, here's my new exception (though perhaps this should be a new post).

When I call SaveChanges() on the manager after adding the LineItem. I get this exception:

IdGenerator problem - not all temp ids converted to permanent ids.
If you are using auto-incrementing ids check that the FixupTempIds SaveOption is set to InSaveListOnly.
This may also occur if your custom IIdGenerator was not found or its GetRealIdMap method did not
provide a corresponding real id for each temp id.
Back to Top
bennage View Drop Down
Newbie
Newbie
Avatar

Joined: 04-Aug-2010
Location: Tallahassee, FL
Posts: 9
Post Options Post Options   Quote bennage Quote  Post ReplyReply Direct Link To This Post Posted: 04-Aug-2010 at 12:43pm
The LineItem is assigned an id (usually 33), I'm not certain where this id comes from.
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post Posted: 05-Aug-2010 at 1:02am

Something is unexpected and unexplained about your model and your application. I cannot reproduce these behaviors using the NorthwindIB tutorial database and the usual out-of-the-box, table-per-type mapping.

Below is my test ... which passes. Because it passes and the wheels come off for you ... even if you later thought you got it to work ... suggests that you have an unusual, possibly corrupt model or that there are steps in the process that are unknown to me. The fact that you have Order.Id == 0 instead of a negative number (indicating a temporary id) indicates another missing piece to the story. I don't suppose you wrote your own custom IdGenerator ... that would be a pertinent fact.
 
The SaveChanges misbehaviors aren't reproducable in my setup either ... which is unsurprising given that I don't have your model or code.
 
I'll need a cutdown version of the model, the edmx, and your code to make progress. Sorry about that.
 
Here's my test. Note that I never bother to talk to the database; I can test the pertinent facts without going near a database.
    [TestMethod]
    public void can_add_lineItem_to_new_detached_order() {

      var mgr = new NorthwindManager(false /* = disconnected */);

      // Pretend we retrieved an existing product
      var prod = new Product
                   {
                     ProductID = 42,
                     ProductName = "Foo",
                   };
      mgr.AttachEntity(prod); // attaches as "unchanged"

      var order = new Order(); // not yet associated with a manager 

      // Create new lineitem which is immediately added to mgr
      // because the assignment of its Product pulls it into
      // the mgr of the "Prod" entity.
      // The act of adding this lineitem to the lineitems of the order
      // causes the new order to be pulled into the mgr as well.
      // All this confirmed in subsequent Asserts.
      order.OrderDetails.Add(new OrderDetail{Product = prod});

      Assert.AreEqual(order.EntityAspect.EntityState, EntityState.Added);
      Assert.AreEqual(1, order.OrderDetails.Count);

      var lineItem = order.OrderDetails.First(); // get the new OrderDetail
 
      Assert.AreEqual(lineItem.EntityAspect.EntityState, EntityState.Added);
      Assert.AreSame(lineItem.Product, prod);
      Assert.AreSame(order.EntityAspect.EntityManager, lineItem.EntityAspect.EntityManager);
      Assert.AreSame(order.EntityAspect.EntityManager, prod.EntityAspect.EntityManager);

    }


Edited by WardBell - 05-Aug-2010 at 1:05am
Back to Top
WardBell View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 31-Mar-2009
Location: Emeryville, CA,
Posts: 338
Post Options Post Options   Quote WardBell Quote  Post ReplyReply Direct Link To This Post Posted: 05-Aug-2010 at 1:36am
A pal of mine offered some additional thoughts:
 

First look at the DebugLog to see if an IdGenerator is being discovered – if not – bingo

If so, have him send the IdGenerator that he is using., or have him debug into his IdGenerator GetRealIdMap method.

 

Or

 

He may be using autoincrement ids and only sending part of the graph – hence the hint about

 

    If you are using auto-incrementing ids check that the FixupTempIds SaveOption is set to InSaveListOnly

 
And how could you be "only sending part of the graph"? You would be doing so if you called
 
   manager.SaveChanges(someEntities) 
 
where "someEntities" is a subset of the entities you changed. 
 
I'm always wary of this overload. It's too easy to omit an entity that has changes and should have been saved with the others. The mistake can mean a data integrity problem.
 
That overload has its place ... but one needs to be certain.
 
You might ask "what is that 'FixupTempIds SaveOption'?".  The DevForce "API Reference" is a good place to learn about it (that's the help file generated from our XML comments; find it from Windows Menu | All Programs | DevForce 2010 ... | Documentation).
 
Turns out you can tune the SaveChanges behavior with a SaveOptions object. SaveOptions has several properties, one of which is FixupTempIds. Its "InSaveListOnly" enum means  "Perform Id fixup only on those entities passed into the SaveChanges method. "
 
Looking at the debug log is ALWAYS a good first step when you're wondering what the server did. If we ask you to send us an example of a problem, we'll want that debug log too.
 
Back to Top
bennage View Drop Down
Newbie
Newbie
Avatar

Joined: 04-Aug-2010
Location: Tallahassee, FL
Posts: 9
Post Options Post Options   Quote bennage Quote  Post ReplyReply Direct Link To This Post Posted: 05-Aug-2010 at 7:42am
I'll send you a sample project for review.
Back to Top
Matt Foley View Drop Down
Newbie
Newbie


Joined: 21-Jul-2011
Location: Birmingham, AL
Posts: 9
Post Options Post Options   Quote Matt Foley Quote  Post ReplyReply Direct Link To This Post Posted: 21-Jul-2011 at 9:58am
I am having the same issue as your second issue,
IdGenerator problem - not all temp ids converted to permanent ids.
If you are using auto-incrementing ids check that the FixupTempIds SaveOption is set to InSaveListOnly.
This may also occur if your custom IIdGenerator was not found or its GetRealIdMap method did not
provide a corresponding real id for each temp id.
However this occurs for me after a EntityManager.RejectChanges(); call.

I have a similar model structure in that I am creating an entity with subentities that are automatically filled with auto-generated int id's on a Create method in the entity's partial class definition.

I have tried the suggestion of specifying the FixupTempIds SaveOption to InSaveListOnly by modifying the Manager's DefaultSaveOptions (because I have no way to pass it in as a param since this is happening in RejectChanges).

Also, saving has no problems.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down