Can I have both Mapped and original column?

8 posts, 0 answers
  1. Robert
    Robert avatar
    40 posts
    Member since:
    Jul 2008

    Posted 30 Apr 2009 Link to this post

    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
  2. Alexander
    Admin
    Alexander avatar
    727 posts

    Posted 01 May 2009 Link to this post

    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.
  3. DevCraft banner
  4. SuperXRAY
    SuperXRAY avatar
    82 posts
    Member since:
    Feb 2007

    Posted 04 May 2009 Link to this post

    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.
  5. Robert
    Robert avatar
    40 posts
    Member since:
    Jul 2008

    Posted 04 May 2009 Link to this post

    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
  6. SuperXRAY
    SuperXRAY avatar
    82 posts
    Member since:
    Feb 2007

    Posted 04 May 2009 Link to this post

    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



  7. SuperXRAY
    SuperXRAY avatar
    82 posts
    Member since:
    Feb 2007

    Posted 04 May 2009 Link to this post

    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.
  8. SuperXRAY
    SuperXRAY avatar
    82 posts
    Member since:
    Feb 2007

    Posted 05 May 2009 Link to this post

    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'.
  9. Jan Blessenohl
    Admin
    Jan Blessenohl avatar
    707 posts

    Posted 06 May 2009 Link to this post

    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.
Back to Top
DevCraft banner