Questions on 2.6 > 3.1 upgrade

Posts   
 
    
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 27-Jul-2011 15:28:45   

Hi,

After having used the 2.6 version (which stated september 2008 in the title of the designer) for almost 3 years we've just converted our projects to 3.1. All went quite well, except for a few things: (I looked at the breaking changes, be couldn't identify matches with our issues)

1. We get the following message at compilation:

'SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.Transaction' is inaccessible due to its protection level

Which I find especially strange since our other LLBLGen projects converted to 3.1 don't seem to have this issue. Also I can't imagine this should be protected. Are we using wrong dll's. We normally use this when we do database queries in in Injectables, we would get the Transaction from the involvedentity and set that to the collection or entity with which we want to do a database lookup.

Find Reference returns:

protected ITransaction Transaction { get; set; }

From SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.

  1. We seem to have hit on a 'reserved' word. We have a Page-Entity and a StaticPageEntity which means we've got a class that's double defined:

PageRelations.cs contains:


    /// <summary>Static class which is used for providing relationship instances which are re-used internally for syncing</summary>
    internal static class StaticPageRelations
    {

        /// <summary>CTor</summary>
        static StaticPageRelations()
        {
        }
    }

and StaticPageRelations.cs contains:


    /// <summary>Implements the relations factory for the entity: StaticPage. </summary>
    public partial class StaticPageRelations
    {
        /// <summary>CTor</summary>
        public StaticPageRelations()
        {
        }

We probably have to rename this entity.

Especially on the first one we would like feedback as we can't compile the code.

Thanks, Gabriƫl

LLBLGen 3.1, SelfServicing, TwoClasses

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 27-Jul-2011 15:52:34   

1- EntityBase.Transaction is protected indeed.

Though you can expose it manually by adding a property to the CommenEntityBase which returns the value of the protected property.

2-You need to re-name your classes especially the one that starts with the "static" word.

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 27-Jul-2011 16:29:39   

Thanks. I was thinking about making it public as well, but there might be a reason it's protected. Or can we still use it in the way we always did?

Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 27-Jul-2011 17:46:46   

cast to ITransactionalElement, and then read the Transaction object. But it's indeed hidden, as you shouldn't set the property manually but use the Add method on the transaction to add an entity to a transaction

Frans Bouma | Lead developer LLBLGen Pro
gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 28-Jul-2011 08:29:37   

For some reason we've always worked this way. If I know re-read the manuals I don't know why.

Would it give possible problems to (temporarily) keep working with this hidden property, or can we do it to speed up the migration and do it a bit later?

In addition to that we also came to this problem:

'SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.SetRelatedEntity(SD.LLBLGen.Pro.ORMSupportClasses.IEntity, string)' is inaccessible due to its protection level

(Also seen here: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=19751&HighLight=1)

CertificationHelper.cs:


        /// <summary> Sets the internal parameter related to the fieldname passed to the instance relatedEntity. </summary>
        /// <param name="relatedEntity">Instance to set as the related entity of type entityType</param>
        /// <param name="fieldName">Name of field mapped onto the relation which resolves in the instance relatedEntity</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        protected override void SetRelatedEntity(IEntity relatedEntity, string fieldName)
        {
            switch(fieldName)
            {
               (...)
            }

Adding this to the CommonEntityBase doesn't work:


        public new void SetRelatedEntity(IEntity relatedEntity, string fieldName)
        {
            this.SetRelatedEntity(relatedEntity, fieldName);
        }

X hides inherited abstract member 'SD.LLBLGen.Pro.ORMSupportClasses.EntityBase.SetRelatedEntity(SD.LLBLGen.Pro.ORMSupportClasses.IEntity, string)'

Thank you.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 28-Jul-2011 09:30:34   

Would it give possible problems to (temporarily) keep working with this hidden property, or can we do it to speed up the migration and do it a bit later?

If you need to access the hidden property just to read the value, then you may keep using them.

Similarly with SetRelatedEntity(). Don't create a new propoerty that hides the existing one, instead override the existing one.

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 02-Aug-2011 11:45:31   

What should be used instead of 'SetRelatedEntity'?

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 02-Aug-2011 14:21:03   

Instead of declaring the method as "public new ". You should declare it as "protected override"

gabrielk avatar
gabrielk
User
Posts: 231
Joined: 01-Feb-2005
# Posted on: 02-Aug-2011 20:53:16   

Understood, and thanks for that.

But I assume it's hidden for a reason, or isn't it replaced by a new way of doing it, or am I wrong in that assumption.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 03-Aug-2011 04:38:53   

gabrielk wrote:

But I assume it's hidden for a reason, or isn't it replaced by a new way of doing it, or am I wrong in that assumption.

It's protected because it's used internally and usually you don't need to call this directly. For instance when you call theProduct.Cagegory = someCategory, the setter will call the EntityBase2.SetSingleRelatedEntityNavigator method and that method call the SetRelatedEntity method of the ProductEntity. So you just need to set it through the property setter.

But if, for some reason, you want more control over this, you can override the method in a partial class or in a derived class, or just to make it public, but first analyze what the code does.

David Elizondo | LLBLGen Support Team
csb1965
User
Posts: 12
Joined: 20-Sep-2011
# Posted on: 20-Sep-2011 03:27:28   

I've also just upgraded to version 3.1 from 2.6 and have a number of error messages relating to the now inaccessible entity.Transaction property.

I am using the Self Servicing model ...

In our code we have used the Transaction property to read the current transaction of a "parent" entity instance and decide whether or not to create a new transaction or use the existing transaction from the "parent" object.

For example, I am creating or modifying various entity instances related to an order for a particular customer within a method like


void ModifyOrder(Customer cust, OrderInfo info) { 
   OrderEntity order = new OrderEntity();

   // set values and add related entities   

   if (cust.Transaction != null) {
      ITransaction tx = cust.Transaction;
      tx.Add(order);  // plus other related entities
   }        

   if (cust.Transaction == null) {
      order.Save(true);
   }
}

Since multiple entities are involved I need to perform the update to the order within a transaction. However, if customer is already within an explicit transaction I need to add my order (and related) entities to this transaction explicitly.

In the past I would 1. Create a local transaction if (cust.Transaction == null) or use that transaction if not null 2. Make the order changes - adding each modified entity to the transaction. 3. If the transaction was "local", commit

I understand that I could override the Transaction property to expose it again but I am concerned that what we have done is not "best practice" use of either LLBLGen or database transaction semantics.

How would you recommend we handle this kind of situation where we have an operation that may or may not be called from within an existing transaction?

I appreciate your thoughts and advice ..

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 20-Sep-2011 06:36:34   

It's an interface thing I think. Please try the following:

if ( ((ITransactionalElement)cust).Transaction != null) {
     ITransaction tx = ((ITransactionalElement)cust).Transaction;
     tx.Add(order); // plus other related entities
}   
David Elizondo | LLBLGen Support Team
csb1965
User
Posts: 12
Joined: 20-Sep-2011
# Posted on: 21-Sep-2011 18:59:35   

Thanks David .. I'll try that out.

Meanwhile, I'm just wondering if I should be doing this differently. Is there a better pattern that you recommend as best practice here?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 22-Sep-2011 02:30:06   

csb1965 wrote:

Meanwhile, I'm just wondering if I should be doing this differently. Is there a better pattern that you recommend as best practice here?

The only thing with that approach is that it seems a little bit obscure, because you don't have control on what is added to the transaction.

public void DoThings()
{
     var tx = new Transaction(...);

     var parent = new ParentEntity();
     tx.Add(parent);

     // don't know what is added to tx.
     OtherThingsToDo(parent);

     tx.Commit();
}

Another way to do this is that you add stuff only in the main sub:

public void DoThings()
{
     var tx = new Transaction(...);

     var parent = new ParentEntity();
     tx.Add(parent);
     parent.Save();

     // just get the entitiy and save it here
     var someChild = CreateChildWithoutSavingIt(parent);
     tx.Add(someChild);
     someChild.Save();
    
     // this would save the child inside this method but we are passing the Transaction to be used
     DoStuffAndAddItToTx(parent, tx);

     tx.Commit();
}

That way you have full control on what is going on with the Transaction in one piece of code. It's just to read clearer the code. That is how I would do that, but it's more a convention thing in your development team.

David Elizondo | LLBLGen Support Team