Solved

Getting error: "The multi-part identifier could not be bound" On Customized Field that is not a mutli-part identifier

  • 15 January 2024
  • 4 replies
  • 113 views

Userlevel 4
Badge

I have seen the The multi-part identifier could not be bound error before, but this time it is giving it on my custom field which is simply a string.

When I run this with the VS2022 debugger running, the error is not caught, so I am not sure where it is even happening in my code. This is the workflow:

  1. create an Opportunity. 
  2. From opportunity, create a “Project Quote”
Creating Project Quote​​​
  1. Convert Project Quote to Project:
Convert to Project

 

  1. Add a row on the revenue budget tab for the project:
Adding Revenue Item

And, when I go to save I get the error message (note the error is in the CROpportunity for some reason:)

Error Message
 

UsrAuthorizedByContact does exist in the SQL Database, and it does have value:

This is the stack trace of the error:

 

System.Data.SqlClient.SqlException (0x80131904): The multi-part identifier "CROpportunity.UsrAuthorizedByContact" could not be bound.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at PX.Data.PXDatabaseProviderBase.ExecuteNonQuery(IDbCommand command)
at PX.Data.PXDatabaseProviderBase.updateCommon(IDbCommand cmd, String tableName, Int32 cid, PXDataFieldParam[] pars, AuditTable audit, Boolean isVisibilityUpdate, Boolean sharedDelete, companySetting setting)
at PX.Data.PXDatabaseProviderBase.<>c__DisplayClass155_0.<update>b__1(String tn, IDbCommand cmd)
at PX.Data.PXDatabaseProviderBase.usingDbCommand[T](Func`3 fnUsefulActions, String commandText, String tableName)
ClientConnectionId:3a2a8162-df10-4bab-8ec1-44766ab90758
Error Number:4104,State:1,Class:16
at PX.Data.PXDatabaseProviderBase.usingDbCommand[T](Func`3 fnUsefulActions, String commandText, String tableName)
at PX.Data.PXDatabaseProviderBase.Update(Type table, PXDataFieldParam[] pars)
at PX.Data.PXCache`1.PersistUpdated(Object row, Boolean bypassInterceptor)
at PX.Data.PXCache`1.Persist(PXDBOperation operation)
at PX.Data.PXGraph.Persist()
at PX.Objects.PM.ProjectEntry.Persist()
at PX.Data.PXSave`1.<HandlerInternal>g__Persist|3_2()
at PX.Data.PXSave`1.<HandlerInternal>d__3.MoveNext()
at PX.Data.PXAction`1.<Press>d__38.MoveNext()
at PX.Data.PXAction`1.<Press>d__38.MoveNext()
at PX.Web.UI.PXBaseDataSource.tryExecutePendingCommand(String viewName, String[] sortcolumns, Boolean[] descendings, Object[] searches, Object[] parameters, PXFilterRow[] filters, DataSourceSelectArguments arguments, Boolean& closeWindowRequired, Int32& adapterStartRow, Int32& adapterTotalRows)
at PX.Web.UI.PXBaseDataSource.ExecuteSelect(String viewName, DataSourceSelectArguments arguments, PXDSSelectArguments pxarguments)

It is worth mentioning that in order to carry the values over from the Opportunity I had to override the dialog box. And I suspect this is where the culprit actually lies. I posted my full class here: 

Previous Thread

My question is two fold:

  1. How do you debug an error, when Acumatica is (apparently) catching and releasing it before the VS2022 Debugger gets to see it?
  2. What do I do to resolve this error?

TIA!

 

icon

Best answer by mjgrice32 17 January 2024, 21:00

View original

4 replies

Userlevel 7
Badge +5

You mentioned that the error indicates that the table is CSOpportunity but you didn’t expect this. What table did you add your custom field to?

Userlevel 4
Badge

You mentioned that the error indicates that the table is CSOpportunity but you didn’t expect this. What table did you add your custom field to?

I’m sorry, I guess I clipped it in the screenshot. That field is in all of the DACs I can imagine are getting used. That screenshot I showed above is from [CROpportunity]

 

Userlevel 4
Badge

For future reference (like for future me, who forgets...)

The issue here was that PMProject Extends Contract, as can be seen by looking at the source code (via ScreenID sm204570):

    using PX.Objects.CT;    
    public partial class PMProject : Contract, IAssign, PX.SM.IIncludable

Because of this, it seems my custom fields have to be added to both PMProject and Objects.CT.Contract, and they need to be defined the same. 

So, in addition to:

    public class PMProjectExt : PXCacheExtension<PMProject>
    {
    
        #region UsrAuthorizedByContact 
        [PXDBString(256)]
        [PXUIField(DisplayName = "Authorized by Contact")]
        public virtual string UsrAuthorizedByContact { get; set; }
        public abstract class usrAuthorizedByContact : PX.Data.BQL.BqlString.Field<usrAuthorizedByContact> { }
        #endregion
    
    }

I also needed:

    public class ContractExt : PXCacheExtension<Contract>
    {
        #region UsrAuthorizedByContact
        [PXDBString(256)]
        [PXUIField(DisplayName = "Authorized by Contact")]
        public virtual string UsrAuthorizedByContact { get; set; }
        public abstract class usrAuthorizedByContact : PX.Data.BQL.BqlString.Field<usrAuthorizedByContact> { }
        #endregion    
    }

I tried it with both [PXDBString(256)] and [PXDBString] and either seemed to work. I kept it as [PXDBString(256)] since that is how it is defined in the SQL database.

If a field were missing from either of them, I got the error. With both defined, it appears to be running fine.

FWIW.


 

Userlevel 7
Badge

Thank you for sharing your solution with the community @mjgrice32!

Reply


About Acumatica ERP system
Acumatica Cloud ERP provides the best business management solution for transforming your company to thrive in the new digital economy. Built on a future-proof platform with open architecture for rapid integrations, scalability, and ease of use, Acumatica delivers unparalleled value to small and midmarket organizations. Connected Business. Delivered.
© 2008 — 2024  Acumatica, Inc. All rights reserved