The EntitySpaces Community

Share and learn about the EntitySpaces Architecture.
Welcome to The EntitySpaces Community Sign in | Join | Help
in
Home Forums Photos

binding to DevExpress grid, "Column 'ContractValue_Sale' does not belong to table ContractualUnit."

Last post 11-20-2007, 1:32 PM by toreandreb. 4 replies.
Sort Posts: Previous Next
  •  11-16-2007, 2:17 AM 6607

    binding to DevExpress grid, "Column 'ContractValue_Sale' does not belong to table ContractualUnit."

    Hi

    I am using EntitySpaces Version 2007.1.1112.0, SQL Server 2005  and Developer Express Grid.

    So, I have a grid that is bound to a ContractualUnitCollection via a bindingsource. The query from ContractualUnit selects a few of the columns from the ContractualUnit table, and also a few fields from joined in tables. Here's the code :

     

     

    Code:
                ContractualUnitQuery masterCUQuery = new ContractualUnitQuery("smaq");
    ContactQuery subPortfolioClientContact = new ContactQuery("subconq");
    ClientQuery subPortfolioClientClient = new ClientQuery("subcliq");
    ServiceQuery serviceQuery = new ServiceQuery("sseq");
    ServiceTypeQuery serviceTypeQuery = new ServiceTypeQuery("sstq");
    CommodityQuery commodityQuery = new CommodityQuery("scmq");
    ConcernQuery concernQuery = new ConcernQuery("sccq");
    ContactQuery contactQuery = new ContactQuery("scoq");
    ClientQuery clientQuery = new ClientQuery("sclq");
    AgreementQuery agreementQuery = new AgreementQuery("sagq");
    ServiceContractQuery serviceContractQuery = new ServiceContractQuery("sscq");
    ContractualUnitQuery contractualUnitQuery = new ContractualUnitQuery("scuq");
    CurrencyQuery currencyQuery = new CurrencyQuery("scrq");
    UnitQuery unitQuery = new UnitQuery("sunq");

    contractualUnitQuery.Select(contactQuery.Name.As("ClientName"), serviceContractQuery.SCId, contractualUnitQuery.SCId, contractualUnitQuery.ServiceTypeId, contractualUnitQuery.RegistrationDate, contractualUnitQuery.SaleDate, contractualUnitQuery.Quantity, contractualUnitQuery.Price, contractualUnitQuery.CommodityId, contractualUnitQuery.SubportfolioClientId, subPortfolioClientContact.Name.As("SubPortfolioClientName"), currencyQuery.CurrencyId, currencyQuery.CurrencyName.As("CurrencyName"), contractualUnitQuery.CUId, concernQuery.ConcernName.As("ConcernName"), serviceTypeQuery.ServiceTypeName.As("ServiceTypeName"), serviceQuery.ServiceName.As("ServiceName"), commodityQuery.CommodityName.As("CommodityName"), masterCUQuery.CUId, contractualUnitQuery.ContractURL, unitQuery.UnitName.As("UnitName"));

    contractualUnitQuery.InnerJoin(serviceContractQuery).On(contractualUnitQuery.SCId == serviceContractQuery.SCId);
    contractualUnitQuery.InnerJoin(commodityQuery).On(contractualUnitQuery.CommodityId == commodityQuery.CommodityId);
    contractualUnitQuery.InnerJoin(serviceTypeQuery).On(contractualUnitQuery.ServiceTypeId == serviceTypeQuery.ServiceTypeId);
    contractualUnitQuery.InnerJoin(currencyQuery).On(contractualUnitQuery.CurrencyId == currencyQuery.CurrencyId);
    contractualUnitQuery.InnerJoin(unitQuery).On(contractualUnitQuery.UnitId == unitQuery.UnitId);
    contractualUnitQuery.LeftJoin(masterCUQuery).On(contractualUnitQuery.ParentCUId == masterCUQuery.CUId);
    contractualUnitQuery.InnerJoin(serviceQuery).On(serviceContractQuery.ServiceId == serviceQuery.ServiceId);
    contractualUnitQuery.InnerJoin(agreementQuery).On(serviceContractQuery.AgreementId == agreementQuery.AgreementId);
    contractualUnitQuery.LeftJoin(concernQuery).On(agreementQuery.ConcernId == concernQuery.ConcernId);
    contractualUnitQuery.InnerJoin(clientQuery).On(agreementQuery.DCClientId == clientQuery.DCClientId);
    contractualUnitQuery.InnerJoin(contactQuery).On(clientQuery.SOClientId == contactQuery.ContactId);
    contractualUnitQuery.LeftJoin(subPortfolioClientClient).On(contractualUnitQuery.SubportfolioClientId == subPortfolioClientClient.DCClientId);
    contractualUnitQuery.LeftJoin(subPortfolioClientContact).On(subPortfolioClientClient.SOClientId == subPortfolioClientContact.ContactId);

    try { mCuList.Load(contractualUnitQuery); } catch (Exception e)
    {
    int i = 0;
    }

    Now, the query does works fine, and the collection binds fine to the grid. However, when I select a ContractualUnit in the grid and then clicks somewhere else, so that the grid loses focus, the "Column 'ContractValue_Sale' does not belong to table ContractualUnit." error occurs. Note that the ContractValue_Sale is the first column in ContractualUnit that is NOT selected in the select statement. If I include it in the select statement, then the next column "ContractValue_Euro" generates the error. This could certainly be something that is going on in DevExpress.

    Here's the stacktrace of the error :

     

    Code:
    at System.Data.DataRow.GetDataColumn(String columnName)\r\n   
    at System.Data.DataRow.get_Item(String columnName)\r\n
    at EntitySpaces.Core.esEntity.GetSystemDecimal(String columnName)\r\n
    at BusinessObjects.esContractualUnit.get_ContractValueSale() in C:\\temp\\sourcecode\\testprojects\\WindowsApplication8\\EntitySpacesLibrary\\Generated\\ContractualUnit.cs:line 653\r\n
    at (Object )\r\n
    at DevExpress.Data.Access.DataListDescriptor.FastPropertyDescriptor.GetValue(Object component)\r\n
    at DevExpress.Data.Helpers.BaseListDataControllerHelper.GetRowValue(Int32 listSourceRow, Int32 column)\r\n
    at DevExpress.Data.DataController.GetRowValue(Int32 controllerRow, Int32 column)\r\n
    at DevExpress.Data.BaseListSourceDataController.GetRowValue(Int32 controllerRow, Int32 column)\r\n
    at DevExpress.Data.ControllerRowValuesKeeper.SaveValues()\r\n
    at DevExpress.Data.CurrencyDataController.EndCurrentRowEdit(Boolean force)"
     

    Finally, all the columns are available to DevExpress at designtime, but I have only used the ones I have selected.

     

    thx

    Tore Andre 

  •  11-16-2007, 5:04 AM 6617 in reply to 6607

    Re: binding to DevExpress grid, "Column 'ContractValue_Sale' does not belong to table ContractualUnit."

    Wow toreandreb, you get the ultimate EntitySpaces query award. Are you saying that you have added fields to the grid in design time that are not being selected at runtime, for instance, the 'ContractValue_Sale' column? I really want to understand what is going on here before this weekends release in case this is a bug so stick with us. Thanx for posting the call stack, that really helps, good job on this post. The GetSystemDecimal() method looks like this:

     

    Code:
    protected System.Decimal? GetSystemDecimal(string columnName)
    {
    if (this.row == null) this.AddNew();

    object o = this.row[columnName];
    return (o == DBNull.Value) ? null : (System.Decimal?)o;
    }

    Notice we don't perform this.row.Table.Columns.Contains(columnName) to ensure the columns exists first, this is how EntitySpaces has always been, ie, if you access an column you don't bring back an exception is thrown. We could of course put that check it but that would have negative impact on performance for sure. I suppose we could cache the DataColumn once accessed, but that kind of change will have to be thought through and not added quickly this weekend.

    So, my question really is why add columns to the grid that you are not bringing back? 



    EntitySpaces | Twitter | BLOG | Please honor our Software License
  •  11-16-2007, 5:41 AM 6620 in reply to 6617

    Re: binding to DevExpress grid, "Column 'ContractValue_Sale' does not belong to table ContractualUnit."

    Thanks for the quick response!

     First, to answer you question : In the DevExpress grid designer (this is design time) , when you select "Columns" for a grid, two lists appear : The Field list and the Column list. The ContractValue_Sale is in the Field list, but not in the Column list. So, the fields in the Column list I selected from the Field list. But I only select Fields that I return in the query.

    Now, here's how all the fields from ContractualUnit are available at design time in the Grid Designer:

    1. After generating the ES code with MyGeneration, the ContractualUnitCollection is made available in the Form designer.

    2. I drag a ContractualUnitCollection into the Form (in which the DevExpress grid is placed).

    3. I drag a bindingsource into the same form.

    4. Set the DataSource of the bindingsource to ContractualUnitCollection that I dragged into the form.

    5. Set the DataSource of the grid to the bindingsource.

     

    In addition to that, I want to be able to show some data from the joined tables. Here's how I made those available to the designer :

     

    Code:
    public partial class ContractualUnit : esContractualUnit
    {
            protected override List GetLocalBindingProperties()
            {
                List props = new List();
    
                props.Add(new esPropertyDescriptor(this, "ClientName", typeof(String)));
                props.Add(new esPropertyDescriptor(this, "ConcernName", typeof(String)));
                props.Add(new esPropertyDescriptor(this, "ServiceTypeName", typeof(string)));
                props.Add(new esPropertyDescriptor(this, "ServiceName", typeof(string)));
                props.Add(new esPropertyDescriptor(this, "CommodityName", typeof(string)));
                props.Add(new esPropertyDescriptor(this, "SubPortfolioClientName", typeof(string)));
                props.Add(new esPropertyDescriptor(this, "CurrencyName", typeof(string)));
                props.Add(new esPropertyDescriptor(this, "UnitName", typeof(string)));
                props.Add(new esPropertyDescriptor(this, "SubServiceName", typeof(string)));
    
                return props;
            }
    
            public String ClientName
            {
                get
                {
                    return (string)GetColumn("ClientName");
                }
            }
    }

    Please note that I have removed all the property getters except for ClientName.

    thx

    Tore Andre
     

  •  11-20-2007, 1:26 PM 6750 in reply to 6620

    Re: binding to DevExpress grid, "Column 'ContractValue_Sale' does not belong to table ContractualUnit."

    Hi

    I thought I'd let you guys know that I posted a question to DevExpress regarding this issue, and here's the answer :

    "Thank you for the question. We have researched this problem and found out that this behavior is by design. It appears that the cause of the problem is in the EntitySpaces suite. The ContractualUnitCollection implements the ITypedList interface and provides property descriptors for all properties of the ContractualUnit object. This causes a situation that when the Grid is about to post data, it tries to obtain all values of the underlying object. This is done to provide the ability to rollback changes if there are any exceptions raised when posting data. However, you can easily bypass this problem by setting the GridView's OptionsBehavior.CacheValuesOnRowUpdating property to "Disabled". This way the Grid will not cache object values before posting data. "

     If I understand DevEx correctly they are basically saying "Heck, you provided a propertydescriptor for this, so you better handle a request for that property". I'm absolutely sure that other users of the EntitySpaces/DevEx combination will run into this exact problem, so I think it must be addressed somehow. Since DevEx, by design, want to keep a copy of all properties, regardless of whether they're used as columns or not, a solution outside DevEx must be found.

    Maybe Mike's idea (above) of checking whether a column exists or not is a solution. Since that check would be placed in the "Generated" code, maybe it could be an option when generating code from MyGeneration, so that this check is done only when specifically asked for?

    regards

    Tore Andre 

  •  11-20-2007, 1:32 PM 6752 in reply to 6750

    Re: binding to DevExpress grid, "Column 'ContractValue_Sale' does not belong to table ContractualUnit."

    And BTW, the workaround suggested by DevExpress works. However, I guess that means that the rollback possibility is not there anymore.

    regards

    Tore Andre 

View as RSS news feed in XML