Adding Items to BusinessListBase

Adding Items to BusinessListBase

Old forum URL: forums.lhotka.net/forums/t/4746.aspx


CyclingFoodmanPA posted on Thursday, April 24, 2008

    I am developing an application utilizing VS2008 and CSLA 3.5 and have a question.  I found a way around this in VS2005 and CSLA 3.0.4, but switched to the latest and greatest a couple of weeks ago before I got too far into the project.

    When I am adding an item utilizing windows forms, for example a Role in PTracker, the Id is automatically created when adding a new item.  It utilizes the GetMax function and I like it creating the Id based on all the previous Id's.  However, when you are in an ASP.NET web application, if you don't enter an Id when you are adding the name, the Id defaults to 0.  Does anyone know how to get the same results for a web application as the Windows?  I am utilizing this method for all my lookup tables and some lookup tables span 5 or 6 pages of the grid and I really don't want a user entering what they think is the next available number.  Yes, it will give them an error if they enter a similar Id to another item, but you don't know my users!  They will be calling asking what this error message means.  They usually just see the error message but don't read it.  Yea, they know something went wrong, but call me and have me check on the error because they cannot understand it.

    Anyway, I figured out a way around it in the previous version, but things are a lot different in CSLA 3.5 and I am utilizing LINQ heavily.  I am lovin' LINQ!

Thank you in advance for your help.

Keith

 

 

CyclingFoodmanPA replied on Thursday, April 24, 2008

Ok,

On my private void Child_Insert() method, I found how to get the next highest Id inserted into the db, but it is not showing on the web form.  Here is what I did:

private void Child_Insert()
{
    using (var mgr = 
        ContextManager<BAS.DalLinq.BAS2005DataContext>.GetManager(
             BAS.DalLinq.
Database.BAS2005))
    {
        System.Data.Linq.
Binary lastChanged = _timestamp;
        _lastChangedBy = Csla.
ApplicationContext.User.Identity.Name;
        short newId = GetMax();

        mgr.DataContext.usp_csla_InsertInventoryIndicator(
            newId,
            ReadProperty<
string>(InventoryIndicatorNameProperty),
            _lastChangedBy,
            ref lastChanged);
       _timestamp = lastChanged.ToArray();

        mgr.DataContext.SubmitChanges();
    }
}

When reselect the web form after insert, the item comes up with the Id.  But if I just hit Insert, the item comes back with an Id of 0, but the correct Id was inserted into the db.  I know it has something to do with LINQ and not refreshing the collection, but not sure how to get around it.  I thought the SubmitChanges would fix that, but it didn't.

Keith

 

 

RockfordLhotka replied on Thursday, April 24, 2008

Your stored procedure must be returning the generated id value?

But your newId parameter isn't declared with 'ref' so the value won't come back from the call.

CyclingFoodmanPA replied on Friday, April 25, 2008

No, the GetMax() get's the Id as it is set up like the Role and Roles in PTracker.  If I don't do the GetMax before the Insert, a 0 gets inserted into the DB for the Id.  With the GetMax, the next highest Id gets inserted into the DB, however, with the web form, the Id that shows is still 0, but the next highest Id is in the DB.  If I go to another web page and come back to this one, the next highest Id shows because the page has been refreshed.  If I enter the next highest Id when I enter the new Inventory Indicator, all works fine, but I don't want the user to have to enter the next highest Id.

Anyway, I hope I will figure it out as it is bugging me.

Keith

RockfordLhotka replied on Friday, April 25, 2008

Oh, in that case I think the problem is that you are setting the GetMax() value into newId, but you are never copying newId into your object’s actual _id field.

 

Rocky

 

CyclingFoodmanPA replied on Tuesday, April 29, 2008

Ok, I figured how to fix things in web forms, however, it messes things up for Windows Forms.  Here is what I do:

private void Child_Insert()
{
    using (var mgr =
        ContextManager<BAS.DalLinq.BAS2005DataContext>.GetManager(
            BAS.DalLinq.
Database.BAS2005))
   
{
        System.Data.Linq.
Binary lastChanged = _timestamp;
       _lastChangedBy = Csla.
ApplicationContext.User.Identity.Name;

       InventoryIndicatorId = this.GetMax();

       mgr.DataContext.usp_csla_InsertInventoryIndicator(
           ReadProperty<
short>(InventoryIndicatorIdProperty),
           ReadProperty<
string>(InventoryIndicatorNameProperty),
          _lastChangedBy,
          ref lastChanged);
       _timestamp = lastChanged.ToArray();
    }
}

Now, that fixes my web forms issue.  However, when  run this code through Windows forms, it adds 1 to the Id so if I have 3 items and add 1, the Id of the next one is 5 because the GetMax is executed when you add the new item, then 1 is added before the Insert.  The Id is 4 if added through web forms though which is what I want.  If you are only using Windows Forms or Web forms, no problem, but if you are to use both, then there is an issue of you are anal (like me) and like all your Id's in succession.

Keith

 

 

 

ajj3085 replied on Tuesday, April 29, 2008

Why aren't you using the db function scope_identity() to get the row id immediately after insert?  If you want a sequencial number id, the column should be an Identity column and you ask the db for the value.  For temporary values to use prior to inserting into the database, I would use a static integer that goes from -1 and continues to be decremented.

Copyright (c) Marimer LLC