This is a migrated thread and some comments may be shown as answers.
Setting reference to another object
10 Answers 123 Views
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
tmlipinski
Top achievements
Rank 1
tmlipinski asked on 26 Feb 2009, 10:14 AM
Hi,

A typical situation:
  • an "Order" table / class
  • a "Customer" table / class
Both tables have integer, autoincremented IDs.
"Order" has a reference to "Customer", of course. It's an integer column named, let's say, CustomerRef.

Now, I have a form for creating a new order. Among others, there is a combo on this form, for selecting a customer. Customers' IDs are the values of items' values. After entering all neccessary data, including selecting a customer, I press "Save". Then, I create a new "Order" object, fill its properties and, finally, I want to set the reference to the selected customer. In database's terms I should just put customer's ID (an integer) to the CustomerRef column (also integer). But CustomerRef property of the Order class is not an integer but Customer class. And this is an issue:
  • I can, of course, use Database.OID.ParseObjectId and <objectscope>.GetObjectById methods to get the Customer object
  • but will this algorithm ask the database for this object? or will it just create a nearly empty object filled with the ID only - wtihout asking the database?

If it is the first case - is there another option for setting the reference?

Regards
Tomasz

10 Answers, 1 is accepted

Sort by
0
Sharbel Lutfallah
Top achievements
Rank 1
answered on 27 Feb 2009, 12:11 AM
Hi Tomasz,

I too struggled with this at first, and my findiings were that your assumption is correct.  Instead of doing:

order.customerID = 5;

You would do :

order.Customer = BLL_MethodToGetCustomer(5);
(obviously a fictitious BLL method that returns the customer object by ID)

I tried to create a new customer object and set a reference to that in the order, but that will try to insert a new customer... 

I believe your assumption is the way it should be done.
0
tmlipinski
Top achievements
Rank 1
answered on 10 Mar 2009, 02:45 PM
Hi,
Thanks. From the functional point of view - it works. But what about efficiency? The key is - whether GetObjectById method asks the database for anything or (required behaviour) just creates an empty object filled with the ID only?
I think the authors of OA, i.e. somebody from the Telerik team should answer this question...

Regards
Tomasz
0
Dimitar Kapitanov
Telerik team
answered on 11 Mar 2009, 03:25 PM
Hi tmlipinski,
The behavior is like: when you request an object by an ID the L1 cache is checked whether there is a materialized object available. If so it is returned. However if the object is not available an empty object is created that has only the ID field initialized. Then after its properties are accessed, it is fetched from the database. Hope that helps.

Greetings,
Dimitar Kapitanov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
tmlipinski
Top achievements
Rank 1
answered on 11 Mar 2009, 07:09 PM
Thanks.
That is exactly what I've expected. And it's another thing that should be exactly written in the documentation.

Regards
Tomasz.
0
Dimitar Kapitanov
Telerik team
answered on 12 Mar 2009, 11:06 AM
Hello tmlipinski,
Yes we will address this in the appropriate way.

Kind regards,
Dimitar Kapitanov
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
tmlipinski
Top achievements
Rank 1
answered on 26 Apr 2009, 10:04 PM
Hi,

Your answer is that IObjectContext.GetObjectById works as follows:
  • look for the object in the cache
  • if found - return this object
  • if not found - return a new, empty object with its ID initialized

I've done an experiment:
    User u = scope.GetObjectById(Database.OID.ParseObjectId(typeof(User), pID.ToString())) as User;
(User is a persistent class, pID is variable containing the user's id)
When I set pID to some nonexistent value (123456) I received the message: 
"No row for EX.Org.BLL.User ('User') GenericOID@1e244 User USR_id=123456 NOTRES "
Evidently OA searched the database.
And it is not bad: if I would ask scope for such a user just to work with it I would expect to receive this message at this moment, not later while accessing any property.
I think that you should add to IObjectContext a new method (GetObjectRef(IObjectId id)) that would explicitly return just a reference and would never access the database. If such a method would be added it would become clear:

  • GetObjectById: look for a real, existing object (in the cache or in the database)
  • GetObjectRef: create just a reference (maybe to a nonexisting object)

Regards
Tomasz

0
Jan Blessenohl
Telerik team
answered on 27 Apr 2009, 04:08 PM
Hi tmlipinski,
The functionality is designed in this way. We want to avoid situations where you get an error too late so that you can not find the real cause. This is why GetObjectById is directly checking the existance of the data.

What do you want to achieve? Why do you think a referenc to non existing data makes sense? You may have a constraint defined on the reference anyway and you will get the exception later in the commit call. And there is really no chance to handle it.

Sincerely yours,
Jan Blessenohl
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
tmlipinski
Top achievements
Rank 1
answered on 27 Apr 2009, 08:28 PM
Hi,

My goal is described in the first post of this thread: I want to set the reference to an object of which I know its ID - but not the object itself. It is the ID of the existing object - so setting this reference makes sense. I have everything I need to set this reference from the SQL point of view: the ID of the object. But it is not enough from the ORM point of view: I still haven't got the object. And to get this object I must access the database - which is absolutely unneccessary.
This is the problem.
The solution is to be able to create a dummy (ghost, fake - call it as you want) object just with its ID set - and nothing else. And with no database access.

Regards
Tomasz
0
Zoran
Telerik team
answered on 16 May 2009, 09:03 AM
Hello tmlipinski,

We have observed your scenario as well as some other similar cases and as a result, giving access to the foreign key fields directly is already part of our to-do list. A temporary workaround for our case is to manually write some code for the desired functionality and that is a field and a property accessing the CustomerID field as well as an app.config entry for the field.
The code should have the following form in the .cs files:
private int customerID; 
 
[FiledAlias("customerID")] 
public int CustomerID 
    get{return this.customerID;} 
    set{this.customerID = value;} 

the app.config entry part of the Order class section should be as the following:
<field name="customerID"
 <extension key="db-column"
  <extension key="db-type" value="INTEGER" /> 
  <extension key="db-column-name" value="CustomerRef" /> 
 </extension> 
</field> 
You should also add the following code in the set method of the Customer reference property. The reason for this is that currently, when you have a direct access to the foreign key, it's value is always the one going in the database.
[Telerik.OpenAccess.FieldAlias("customer")] 
public Customer Customer  
    get { return customer; } 
    set 
    { 
        this.customer= value; 
        customerID= customer.customerID; 
    } 


We are sorry for the delayed answer and once again I notice that this workaround is only temporary, in future the process will be much more automatized and manual code-behind or calling GetObjectById() will not be required in these circumstances.

Sincerely yours,
Zoran
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
tmlipinski
Top achievements
Rank 1
answered on 17 May 2009, 08:02 PM
Hi,
Thanks a lot for the detailed discussion of this issue.

Regards
Tomasz
Tags
Getting Started
Asked by
tmlipinski
Top achievements
Rank 1
Answers by
Sharbel Lutfallah
Top achievements
Rank 1
tmlipinski
Top achievements
Rank 1
Dimitar Kapitanov
Telerik team
Jan Blessenohl
Telerik team
Zoran
Telerik team
Share this question
or