Skip to main content

Notifications

Announcements

No record found.

Finance | Project Operations, Human Resources, ...
Unanswered

add recId field to entity

(3) ShareShare
ReportReport
Posted on by 1,289
Hi,
 
I created a table with the following fields (Table1)
Number    Id       codeX      codeY      Field1
------        ---      -------      -------     --------
1               id1     codex1     codey1      fieldz
2               id2     codex1     codey1      fieldz

index "Idx" with allow duplicate No is "Number"
replacement key index is "Idx"
I created a field group with CodeX only to use it in the form

I added Table1RecId field to 'SalesLine' table where the relation is: Table1.RecId == SalesLine.Table1RecId
This field appears in "SalesTable" form with replacement fieldGroup having CodeX only
 
Now i want to be able to import CodeX via SalesOrderLineV2Entity

i added table1 as a read data source to the entity (outer join salesLine). I added CodeX to the entity fields and the staging table.
I also added Table1RecId from SalesLine to the entity fields, and made it private.

Now when i import, i'm getting this error: 
"Matching record for the read only data source 'Table1' does not exist"
Categories:
  • .. Profile Picture
    .. 1,289 on at
    add recId field to entity
    Hi Martin,

    I already tried the code below and it didn't work, i got this error:
    Matching record for the read only data source 'Table1' does not exist

    when I did this, Table1RecId was added to the entity fields
    [ExtensionOf(tableStr(SalesOrderLineV2Entity))]
    final class SalesOrderLineV2Entity_Extension
    {
        public void mapEntityToDataSource(DataEntityRuntimeContext _entityCtx, DataEntityDataSourceRuntimeContext _dataSourceCtx)
        {
    
            next mapEntityToDataSource(_entityCtx, _dataSourceCtx);
    
            switch (_dataSourceCtx.name())
            {
                case dataEntityDataSourceStr(SalesOrderLineV2Entity, SalesLine):
                    SalesLine salesline = _dataSourceCtx.getBuffer() as SalesLine;
                    
                    Table1 table1Local;
                    select firstonly table1Local where table1Local.Id == this.Id //this is coming from salesLine
                        && table1Local.CodeY == this.ItemNumber  //this is coming from salesLine
                        && table1Local.CodeX == this.CodeX  //this is coming from table1
                        && table1Local.IsActive == true;
    
    
                    salesline.Table1RecId = table1Local.RecId;
    
                    break;
    
            }
        }

    1. So do you mean i should remove Table1RecId field from the entity fields? and use "SalesLine.Table1RecId" instead of "this.Table1RecId"?


    I found a workaround by adding Number field to the entity fields, and doing this and SalesLine.Table1.RecId got filled automatically somehow
    *Note: Number is the unique index of table1
        public void mapEntityToDataSource(DataEntityRuntimeContext _entityCtx, DataEntityDataSourceRuntimeContext _dataSourceCtx)
        {
            next mapEntityToDataSource(_entityCtx, _dataSourceCtx);
    
            switch (_dataSourceCtx.name())
            {
                case dataEntityDataSourceStr(SalesOrderLineV2Entity, SalesLine):
                    if (this.CodeX != '' && this.Number == '')
                    {
                        Table1 table1Local;
                        select firstonly Number,RecId from table1Local 
                            where table1Local.Id == this.Id
                                && table1Local.CodeY == this.ItemNumber
                                && table1Local.CodeX == this.CodeX
                                && table1Local.IsActive == true;
    
                        this.Number = table1Local.Number;
                    }
                    break;
            }
        }

    2. but I wanted to do it without adding Number field, as this shouldn't be available for import.
    And here I used this.Number instead of table1.Number
    I'm not sure if it's better to get the buffer and use table1 instead of this

    3. So how can i make it work without adding Number field, and making the import successfully where Table1RecId will be set by code?

     
  • Martin Dráb Profile Picture
    Martin Dráb 230,569 Most Valuable Professional on at
    add recId field to entity
    Okay, let me try to explain it once more. A data entity has data sources, such as SalesOrderLineV2Entity entity has SalesLine data source. Both have fields, but an entity field isn't the same thing as a data source field. You can use code to set a value of a data source field even if there is no entity field mapped to this data source field. You already had code where you assigned a value of SalesLine.Table1RecId, which is the data source, not the entity field, therefore it's an example of an assignment of a data source field when no entity field for Table1RecId is needed.
     
    Now you should anderstand that your statement "I want to set SalesLine.Table1RecId by code, if i make it public then it will be visible to import" mixes two different things. SalesLine.Table1RecId is a data source field, not an entity field. You mean an entity field when talking about making it visible for import, but that's irrelevant if you "want to set SalesLine.Table1RecId by code".
  • .. Profile Picture
    .. 1,289 on at
    add recId field to entity
    Hi Martin,

    the question in the other thread was sth else, i was trying to find workarounds if I don't find an answer for this question.

    Here, I want to set SalesLine.Table1RecId by code, if i make it public then it will be visible to import and i don't want that
     
    how to do that?
  • Martin Dráb Profile Picture
    Martin Dráb 230,569 Most Valuable Professional on at
    add recId field to entity
    1. The disadvatage of a virtual field is that you need to do everything in code and you get a worse performance.
     
    3. There is no universally correct way. These are simply two different things, each with its own purpose. For example, you ask in another thread how you assign a value of a field that doesn't exist as an entity field. But you see that you can assign fields of SalesLine data source, even if they aren't mapped to any entity fields.
     
    4. I think you already what a data source is; we keep talking about them the whole time.
  • .. Profile Picture
    .. 1,289 on at
    add recId field to entity
    1. What are the disadvantages of adding CodeX as virtual field instead of datasource?  

    Remember i said that "Number" field in table1 is unique, when i added this field to the entity and staging, when i wrote this code below to set Number instead, then it worked and i was able to set Number by code even if it's empty in the excel file, and Table1RecId got set by itself because of Number field was set and there was no need to write anything for it

    But the thing is I don't want to add 'Number' to the entity, i want to set SalesLine.Table1RecId by code, if i make it public then it will be visible to import and i don't want that
    [ExtensionOf(tableStr(SalesOrderLineV2Entity))]
    final class SalesOrderLineV2Entity_Extension
    {
        public void mapEntityToDataSource(DataEntityRuntimeContext _entityCtx, DataEntityDataSourceRuntimeContext _dataSourceCtx)
        {
    
            next mapEntityToDataSource(_entityCtx, _dataSourceCtx);
    
            switch (_dataSourceCtx.name())
            {
                case dataEntityDataSourceStr(SalesOrderLineV2Entity, SalesLine):
                    
                    Table1 table1Local;
                    select firstonly table1Local where table1Local.Id == this.Id
                        && table1Local.CodeY == this.ItemNumber
                        && table1Local.CodeX == this.CodeX
                        && table1Local.IsActive == true;
    
                    this.Number = table1Local.Number;
                    //this.Table1RecId = table1Local.RecId;
    
                    break;
                case dataEntityDataSourceStr(SalesOrderLineV2Entity, Table1):
                    //Table1 table1 = _dataSourceCtx.getBuffer() as Table1;
    
                    break;
    
            }
        }
    


    2. Table1RecId field exists in SalesLine, that's why i think my code should be under salesLine switch case and not table1 switch case
     
    3. I think using 'this' is the correct thing, but when looking at standard code, i saw some examples where there is code that says salesLine = instead of this = and they don't update afterwards so i got confused. 
     
    4. When you say "If you want to use CodeX as field mapped to Table1 datasource" Do you mean like lookup, that it returns values that exists in this table? sorry but i'm just trying to understand what you mean
  • Martin Dráb Profile Picture
    Martin Dráb 230,569 Most Valuable Professional on at
    add recId field to entity
    1. Regarding "I need Table1 datasource, because CodeX exists in Table1 and I want the user to provide a value in this field in order to set salesLine.Table1RecId": You surely can use a data source (that's the usual approach), but you're wrong in thinking that it's the only possible solution. You could create CodeX as a virtual field.
     
    Keep the field public for now. We can look at that later if needed.
     
    2. It depends on what you mean by "the code". You current code use just Table1, therefore I assume you've already answered that.
     
    3. If you know the basics of object-oriented programming, you know that this variable refers to the current object. Your code is inside an entity, therefore it refers to the entity.
    It should be clear that salesLine = _dataSourceCtx.getBuffer() obtains a value of SalesLine table buffer.
     
    4. If you want to use CodeX as field mapped to Table1 datasource, then you indeed need Table1 datasource. But it's not the only possible way.
  • .. Profile Picture
    .. 1,289 on at
    add recId field to entity
    Hi @Martin Dráb

    I'm just tagging you so that you can see my reply below. 

    thanks
  • .. Profile Picture
    .. 1,289 on at
    add recId field to entity
    Hi Martin​​​​​​​,

    I need Table1 datasource, because CodeX exists in Table1 and I want the user to provide a value in this field in order to set salesLine.Table1RecId
     
     
    1. I added the breaks, but now when i use this.Table1RecId i'm getting this error
    Field Table1RecId is private and can only be referenced from within the element in which it is declared, how to fix that?
    [ExtensionOf(tableStr(SalesOrderLineV2Entity))]
    final class SalesOrderLineV2Entity_Extension
    {
        public void mapEntityToDataSource(DataEntityRuntimeContext _entityCtx, DataEntityDataSourceRuntimeContext _dataSourceCtx)
        {
            //SalesLine salesLine;
    
            next mapEntityToDataSource(_entityCtx, _dataSourceCtx);
    
            switch (_dataSourceCtx.name())
            {
                case dataEntityDataSourceStr(SalesOrderLineV2Entity, SalesLine):
                    //salesLine = _dataSourceCtx.getBuffer() as SalesLine;
                    break;
                case dataEntityDataSourceStr(SalesOrderLineV2Entity, Table1):
                    //Table1 table1 = _dataSourceCtx.getBuffer() as Table1;
    
                    Table1 table1Local;
                    select firstonly table1Local where table1Local.Id == this.Id
                        && table1Local.CodeY == this.ItemNumber
                        && table1Local.CodeX == this.CodeX
                        && table1Local.IsActive == true;
    
                    //salesLine.Table1RecId = table1Local.RecId;
                    this.Table1RecId = table1Local.RecId;
                    break;
    
            }
        }
    
    }
     
    2. Shall i add the code when the switch case is SalesLine or when the switch case is Table1?
     
    3. Do i need those sentences for anything? when to use "this" and when to use getBuffer()?
    Table1 table1 = _dataSourceCtx.getBuffer() as Table1
    salesLine = _dataSourceCtx.getBuffer() as SalesLine;

     
    4.  I didn't understand this: what do you mean if i want Table1 datasource? in export, i only want codeX value to appear that's why i added it to the entity. can you please explain further?
    There are quite a few other possible solutions, with different behavior. In your case, if you want the Table1 data source (to fetch some field values on export), you may want to find the whole buffer and assign it with setBuffer(). You'll find a plenty of examples if you look at references of DataEntityDataSourceRuntimeContext.setBuffer().
     
  • Martin Dráb Profile Picture
    Martin Dráb 230,569 Most Valuable Professional on at
    add recId field to entity
    Well, maybe you've added an entity field for Table1RecId, but you don't use it in your code, therefore it's not used for anything.
     
    You need to decide whether you want to use it (and change your code) or not (and then you can throw it away).
     
    I meant something like this:
    this.Table1RecId = Table1::findFirstByCodes(this.ItemId, this.CodeX).RecId;
    Then you don't even need any data source for Table1. Note that this example uses Table1RecId field on the entity.

    There are quite a few other possible solutions, with different behavior. In your case, if you want the Table1 data source (to fetch some field values on export), you may want to find the whole buffer and assign it with setBuffer(). You'll find a plenty of examples if you look at references of DataEntityDataSourceRuntimeContext.setBuffer().
     
    One obvious bug in your code is that you forgot to use break; statements to end the cases. When you fix it, you'll also find that salesLine is empty when you try to read values from it (because it's initialized only when the method is called for SalesLine data source, not Table1). You would have easily seen these problems if you walked through your code in debugger. In your own interest, learn how to do it.
     
    And when you get an error, look at where it's thrown. And if you need help from others, share this information with them.
  • .. Profile Picture
    .. 1,289 on at
    add recId field to entity
    Hi Martin,

    yes i already added the Table1RecId field as private.

    But with the code i showed you in the screenshot, it still didn't work ( i got the same error when importing). What's wrong with the code?
    is it the way i'm trying to get the SalesLine?

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Congratulations 2024 Spotlight Honorees

Kudos to all of our 2024 community stars! 🎉

Meet the Top 10 leaders for December

Congratulations to our December super stars! 🥳

Start Your Super User Journey Pt 2

Join the ranks of our community heros! 🦹

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,883 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,569 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans