This is a migrated thread and some comments may be shown as answers.

Can I have both Mapped and original column?

7 Answers 107 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Robert
Top achievements
Rank 2
Robert asked on 30 Apr 2009, 02:16 PM
Hi There,

I currently have set up in reverse mapping each of my foreign keys as references to the appropriate domain object which makes coding against the object model very easy.  I've noticed that that once I map a column as a reference, the original property of the base type is no longer available and I'm not sure how to get it.  

For exampleTableA references TableB so in the generated code I will have a property like:

public Guid TableBID {}

When I create a reference via TableBID so in reverse mapping I create a reference.  Now in the generated code I have a property like:

public TableB MyTableBReference {}

My problem is that I'd like BOTH available in my generated class and I am not sure how to make that happen.  The reason I want both is because I refer to this reference quite often and need the TableBID often as well.  If TableBID is available I can avoid having to load the entire TableB class everytime to get its ID for those cases when that's all I need.

Thanks,
Robert

7 Answers, 1 is accepted

Sort by
0
Alexander
Telerik team
answered on 01 May 2009, 10:12 AM
Hi Robert,

The point of that behavior is that you should not have an object reference and a separate property to this object's id at the same time. This could lead to inconsistencies. For example if you assign a new value to the TableBID property, the class reference will not be automatically associated with the class instance with this id and vice versa. I am afraid you will have to choose and use only one of those two approaches.

Regards,
Alexander
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
SuperXRAY
Top achievements
Rank 2
answered on 04 May 2009, 07:09 PM
Robert,

If you still want to know how to do this, please reply in here and I'll post the directions and coding required. It is actually fairly easy...but in a big project can be quite time consuming.

I have requested this be resolved by Telerik, but I haven't gotten much help regarding that. Somewhat understandingly, it violates the domain model, but web applications aren't object-oriented beasts by nature.
0
Robert
Top achievements
Rank 2
answered on 04 May 2009, 07:17 PM
Hey Super,

Yes please, I would be interested.  I understand the concerns of exposing such a property along with the references object and the potential of getting into a weird state, however, in my case I want it for performance reasons and will be happy with a readonly property, that is, without the ability to set the value and get things mucked up.

Thanks in advance!
Robert
0
SuperXRAY
Top achievements
Rank 2
answered on 04 May 2009, 07:51 PM
Robert,

I have used this extensively lately, with no problems what so ever. Problem is when you Merge Schema Changes or refresh things in the ORM Wizard, you lose all of it, but, here you go...I HATE that the ORM has Partial Class Generation, so I always turn it off. Class files should be all-inclusive, defining both the Private and Public properties and fields.

I generated the below class as an example from a working project. I left _countryId and _stateId as they were for a reason, please ignore them for now. The field/property _job is what I will be discussing. By default, this is how the ORM reverse maps items in your database because it knows that the column "job_id" in the JobOrigin table references the Jobs table, via the FK constraints. Of course, you know this great because it makes it truly Object-oriented, but sucks for those apps that aren't OO. Take a look, _job Gets/Sets a Job object, not an integer (which you already know):
 
 
Imports System.Collections.Generic  
 
 
' Generated by Telerik OpenAccess  
<Telerik.OpenAccess.Persistent(IdentityField:="_id")> _  
Public Class JobOrigin  
 
    Private Dim _id As Integer 'pk  
 
    Private Dim _city As String 
 
    Private Dim _countryId As Integer 
 
    Private Dim _line1 As String 
 
    Private Dim _line2 As String 
 
    Private Dim _stateId As Integer 
 
    Private Dim _zipCode As String 
 
    Private Dim _job As Job  
 
 
    Public Sub New()  
    End Sub 
 
    <Telerik.OpenAccess.FieldAlias("_id")> _  
    Public Property Id() As Integer 
        Get 
            Return _id  
        End Get 
        SetByVal Value As Integer )  
            Me._id = Value  
        End Set 
    End Property 
   
    <Telerik.OpenAccess.FieldAlias("_city")> _  
    Public Property City() As String 
        Get 
            Return _city  
        End Get 
        SetByVal Value As String )  
            Me._city = Value  
        End Set 
    End Property 
   
    <Telerik.OpenAccess.FieldAlias("_countryId")> _  
    Public Property CountryId() As Integer 
        Get 
            Return _countryId  
        End Get 
        SetByVal Value As Integer )  
            Me._countryId = Value  
        End Set 
    End Property 
   
    <Telerik.OpenAccess.FieldAlias("_line1")> _  
    Public Property Line1() As String 
        Get 
            Return _line1  
        End Get 
        SetByVal Value As String )  
            Me._line1 = Value  
        End Set 
    End Property 
   
    <Telerik.OpenAccess.FieldAlias("_line2")> _  
    Public Property Line2() As String 
        Get 
            Return _line2  
        End Get 
        SetByVal Value As String )  
            Me._line2 = Value  
        End Set 
    End Property 
   
    <Telerik.OpenAccess.FieldAlias("_stateId")> _  
    Public Property StateId() As Integer 
        Get 
            Return _stateId  
        End Get 
        SetByVal Value As Integer )  
            Me._stateId = Value  
        End Set 
    End Property 
   
    <Telerik.OpenAccess.FieldAlias("_zipCode")> _  
    Public Property ZipCode() As String 
        Get 
            Return _zipCode  
        End Get 
        SetByVal Value As String )  
            Me._zipCode = Value  
        End Set 
    End Property 
   
    <Telerik.OpenAccess.FieldAlias("_job")> _  
    Public Property Job() As Job  
        Get 
            Return _job  
        End Get 
        SetByVal Value As Job )  
            Me._job = Value  
        End Set 
    End Property 
   
 
 
End Class 

Now, take a look at the app.config file. The snippet for the above class:
<class name="JobOrigin">  
            <field name="_id">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="id" /> 
              </extension> 
            </field> 
            <field name="_city">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="city" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="50" /> 
              </extension> 
            </field> 
            <field name="_line1">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="line_1" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="75" /> 
              </extension> 
            </field> 
            <field name="_line2">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="line_2" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="75" /> 
              </extension> 
            </field> 
            <field name="_zipCode">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="zip_code" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="50" /> 
              </extension> 
            </field> 
            <extension key="db-index" value="IX_job_origins">  
              <extension key="field-name" value="_job" /> 
              <extension key="db-unique" value="true" /> 
            </extension> 
            <field name="_countryId">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="country_id" /> 
              </extension> 
            </field> 
            <field name="_stateId">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="state_id" /> 
              </extension> 
            </field> 
            <field name="_job">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="job_id" /> 
              </extension> 
            </field> 
            <extension key="db-do-not-create-table" value="true" /> 
            <extension key="db-table-name" value="job_origins" /> 
            <extension key="db-optimistic-locking" value="changed" /> 
          </class> 

Notice how the <field name="_job"> is setup. This, in combination with the class file, is how the ORM determines what to do with the values. If you want BOTH a _job As Job Object property AND a _jobId As JobId Integer property, simply make the app.config file look like:
          <class name="JobOrigin">  
            <field name="_id">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="id" /> 
              </extension> 
            </field> 
            <field name="_city">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="city" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="50" /> 
              </extension> 
            </field> 
            <field name="_line1">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="line_1" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="75" /> 
              </extension> 
            </field> 
            <field name="_line2">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="line_2" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="75" /> 
              </extension> 
            </field> 
            <field name="_zipCode">  
              <extension key="db-column">  
                <extension key="db-type" value="VARCHAR" /> 
                <extension key="db-column-name" value="zip_code" /> 
                <extension key="db-sql-type" value="nvarchar" /> 
                <extension key="db-length" value="50" /> 
              </extension> 
            </field> 
            <extension key="db-index" value="IX_job_origins">  
              <extension key="field-name" value="_job" /> 
              <extension key="db-unique" value="true" /> 
            </extension> 
            <field name="_countryId">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="country_id" /> 
              </extension> 
            </field> 
            <field name="_stateId">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="state_id" /> 
              </extension> 
            </field> 
            <field name="_job">  
              <extension key="db-column">  
                <extension key="db-type" value="INTEGER" /> 
                <extension key="db-column-name" value="job_id" /> 
              </extension> 
            </field> 
                        <field name="_jobId">  
                            <extension key="db-column">  
                                <extension key="db-type" value="INTEGER" /> 
                                <extension key="db-column-name" value="job_id" /> 
                            </extension> 
                        </field> 
            <extension key="db-do-not-create-table" value="true" /> 
            <extension key="db-table-name" value="job_origins" /> 
            <extension key="db-optimistic-locking" value="changed" /> 
          </class> 

I indented the new field for visual reasons, <field name="_jobId">. This tells the ORM code that whatever property in your class file has the FieldAlias attribute of "_jobId" maps to the job_id column in the database. now, make your class file look like:
 
 
Imports System.Collections.Generic  
 
 
' Generated by Telerik OpenAccess  
<Telerik.OpenAccess.Persistent(IdentityField:="_id")> _  
Public Class JobOrigin  
 
    Private _id As Integer 'pk  
 
    Private _city As String 
 
    Private _countryId As Integer 
 
    Private _line1 As String 
 
    Private _line2 As String 
 
    Private _stateId As Integer 
 
    Private _zipCode As String 
 
    Private _job As Job  
 
    Private _jobId As Integer 
 
 
    Public Sub New()  
    End Sub 
 
    <Telerik.OpenAccess.FieldAlias("_id")> _  
    Public Property Id() As Integer 
        Get 
            Return _id  
        End Get 
        Set(ByVal Value As Integer)  
            Me._id = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_city")> _  
    Public Property City() As String 
        Get 
            Return _city  
        End Get 
        Set(ByVal Value As String)  
            Me._city = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_countryId")> _  
    Public Property CountryId() As Integer 
        Get 
            Return _countryId  
        End Get 
        Set(ByVal Value As Integer)  
            Me._countryId = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_line1")> _  
    Public Property Line1() As String 
        Get 
            Return _line1  
        End Get 
        Set(ByVal Value As String)  
            Me._line1 = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_line2")> _  
    Public Property Line2() As String 
        Get 
            Return _line2  
        End Get 
        Set(ByVal Value As String)  
            Me._line2 = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_stateId")> _  
    Public Property StateId() As Integer 
        Get 
            Return _stateId  
        End Get 
        Set(ByVal Value As Integer)  
            Me._stateId = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_zipCode")> _  
    Public Property ZipCode() As String 
        Get 
            Return _zipCode  
        End Get 
        Set(ByVal Value As String)  
            Me._zipCode = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_job")> _  
    Public Property Job() As Job  
        Get 
            Return _job  
        End Get 
        Set(ByVal Value As Job)  
            Me._job = Value  
        End Set 
    End Property 
 
    <Telerik.OpenAccess.FieldAlias("_jobId")> _  
    Public Property JobId() As Integer 
        Get 
            Return _jobId  
        End Get 
        Set(ByVal value As Integer)  
            Me._jobId = value  
        End Set 
    End Property 
 
End Class 

Notice I added a Private _jobId As Integer, in the upper portion of the class file - right after the Private _job and a Public Property JobId As Integer at the end of the class.

Now when you build, you can reference the JobOrigin.Job and the JobOrigin.JobId. Mine is not read-only, because I use a lot of drop downs to the set the JobId value...and so far with 300 classes throughout many projects, things are working just fine. Whether you would have an inconsistency or not depends 100% on what you are doing and how your code works, so I take no responsibility if there is a consistency problem. I can only vouch for what my apps do. One could actually make objects smart enough to never have consistency problems, but they would violate domain model and n-tiered layer access rules...even though the object would be much smarter.

So, to recap what I did:

1. Add field mapping definition to app.config.
2. Add Private declaration to <objectclass>.vb file.
3. Add Public declaration and Get/Set methods to <objectclass>.vb file.
4. Build and use.


Now, to elaborate on what you might be doing, since you said you could use a read-only property. You would do the same things as above (or at least I would), but you could declare the Public property read-only and the Get method would look like:
 <Telerik.OpenAccess.FieldAlias("_jobId")> _     
    Public ReadOnly Property JobId() As Integer    
        Get    
            Return _job.Id     
        End Get     
    End Property    
 

I don't know what your classes look like or what your DB looks like, so the above example may be inaffective. All my classes/tables have ID columns.

Let me know if this helps...
Mitch



0
SuperXRAY
Top achievements
Rank 2
answered on 04 May 2009, 07:56 PM
Sorry, my type...It would not be Return _job.Id, it would simply be Return _jobId. Your fetch plans would change if you used the first one.
0
SuperXRAY
Top achievements
Rank 2
answered on 06 May 2009, 03:13 AM
Just an update...this no longer works in 2009.1.423.2 (internal build). I guess I'm forced to slow down my web apps and increase the code-behind required for simple operations.

I have tried multiple variations of my example on the current internal build, but nothing has worked. I feel bad now that I've posted an out-dated 'workaround'.
0
Jan Blessenohl
Telerik team
answered on 06 May 2009, 01:58 PM
Hello SuperXRAY,
I tried it out and it works. Here is the forward mapped test that I did. In reverse case you just have to add the property with field and the mapping node.

Best wishes,
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.
Tags
Development (API, general questions)
Asked by
Robert
Top achievements
Rank 2
Answers by
Alexander
Telerik team
SuperXRAY
Top achievements
Rank 2
Robert
Top achievements
Rank 2
Jan Blessenohl
Telerik team
Share this question
or