New Posts New Posts RSS Feed: DomainModelTemplate
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

DomainModelTemplate

 Post Reply Post Reply
Author
Vonzkie View Drop Down
Senior Member
Senior Member
Avatar

Joined: 01-Aug-2011
Location: PH
Posts: 133
Post Options Post Options   Quote Vonzkie Quote  Post ReplyReply Direct Link To This Post Topic: DomainModelTemplate
    Posted: 15-Aug-2012 at 12:42am
Hi,

I have read about DomainModelTemplate to customize code generation, however, i don't have resource materials to review. 
Here's what I want to accomplished, all of our Entities have intConcurrencyID field, we want to automate the process using DomainModelTemplate to make the field ConcurrencyStrategy to AutoIncrement and the ConcurrencyMode to Fixed.

This is my first attempt to do it:

public class MyTemplate : DomainModelTemplate {

    public MyTemplate(Microsoft.VisualStudio.TextTemplating.TextTransformation textTransformation)
           : base(textTransformation) {}

    protected override void WriteEntityDataPropertyAttributes(EdmPropertyWrapper property) {
if (property.Name == "intConcurrencyID") {
WriteAttribute("IbEm.ConcurrencyStrategy(IbEm.ConcurrencyStrategy.AutoIncrement)");
}

        base.WriteEntityDataPropertyAttributes(property);
    }
}

I successfully add attribute to my field but the problem is the PropertyMetadata,

public static readonly IbEm.DataEntityProperty<tblSMSecurityListing, int> intConcurrencyID = new IbEm.DataEntityProperty<tblSMSecurityListing, int>("intConcurrencyID", false, false, IbEm.ConcurrencyStrategy.None, false, null);

The ConcurrencyStrategy is still set to none and i don't know how to edit this using the DomainModelTemplate.

Can you help me on this and if you could provide me some tutorials on how to customize a Devforce model using that technique?

Thanks,
Von


Back to Top
Vonzkie View Drop Down
Senior Member
Senior Member
Avatar

Joined: 01-Aug-2011
Location: PH
Posts: 133
Post Options Post Options   Quote Vonzkie Quote  Post ReplyReply Direct Link To This Post Posted: 15-Aug-2012 at 3:18am
I tried adding to my code and I ended up doing this:

public MyTemplate(Microsoft.VisualStudio.TextTemplating.TextTransformation textTransformation)
           : base(textTransformation) {}

    protected override void WriteEntityDataPropertyAttributes(EdmPropertyWrapper property) {
if (property.Name == "intConcurrencyID") {
WriteAttribute("IbEm.ConcurrencyStrategy(IbEm.ConcurrencyStrategy.AutoIncrement)");
}

        base.WriteEntityDataPropertyAttributes(property);
    }

       protected override void WriteDataEntityPropertyDefinition(EdmPropertyWrapper property)
       {
           if (property.Name == "intConcurrencyID")
           {
               WriteLine(String.Format("/// <summary>The {0} <see cref=\"T:IbEm.DataEntityProperty\"/>. </summary>", property.Name));

               var type = property.IsNullable ? "System.Nullable<int>" : "int";

               WriteLine(String.Format("public static readonly IbEm.DataEntityProperty<{0}, {1}> intConcurrencyID = new IbEm.DataEntityProperty<{0}, {1}>(\"intConcurrencyID\", {2}, false, IbEm.ConcurrencyStrategy.AutoIncrement, false, null);", property.ParentType.Name, type, property.IsNullable.ToString().ToLower()));
           }
           else
           {
               base.WriteDataEntityPropertyDefinition(property);
           }
       }
}


I was able to replace this part:
public static readonly IbEm.DataEntityProperty<tblSMSecurityListing, int> intConcurrencyID = new IbEm.DataEntityProperty<tblSMSecurityListing, int>("intConcurrencyID", false, false, IbEm.ConcurrencyStrategy.None, false, null);

However, concurrency is not yet working and I really need to configure it manually in the EDM designer by setting the columns' ConcurrencyStrategy and ConcurrencyMode for it to work properly.

I thought that EntityManager just look on the designer.cs stuffs to perform concurrency checking but it seems that edmx csdl should be sync with the code behinf or I just missed something here?

Thanks,
Von

Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 15-Aug-2012 at 9:28am
Von,
Concurrency detection is performed by EntityFramework not DevForce as described below. DevForce adds the ability to maintain the concurrency column for you, that's what the ConcurrencyStrategy does. But concurrency detection is performed by EF and it only does it if the EDM has the "Concurrency Mode" set to "Fixed".




Edited by mgood - 15-Aug-2012 at 9:29am
Back to Top
Vonzkie View Drop Down
Senior Member
Senior Member
Avatar

Joined: 01-Aug-2011
Location: PH
Posts: 133
Post Options Post Options   Quote Vonzkie Quote  Post ReplyReply Direct Link To This Post Posted: 15-Aug-2012 at 7:18pm
Hi,

So you mean to say there's no way in DomainModelTemplate or T4 Template that we can accomplish this?

Thanks,
Von
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 15-Aug-2012 at 7:51pm
Yes, that's what I'm saying. If you want to control domain model aspects such as concurrency detection from your code, you have to switch to Code-First.
 
 
With Code-First you can take care of such things very elegantly in a base class that all your entities extend from. The following is an example of such a base class that you can find demonstrated in the Cocktail Reference Application.
 
 
    [ProvideEntityAspect]
    [DataContract(IsReference = true)]
    [RequiresAuthentication]
    public abstract class EntityBase
    {
        private EntityFacts _entityFacts;
 
        [NotMapped]
        public EntityFacts EntityFacts
        {
            get { return _entityFacts ?? (_entityFacts = new EntityFacts(this)); }
        }
 
        [DataMember]
        [ConcurrencyCheck]
        [ConcurrencyStrategy(ConcurrencyStrategy.AutoIncrement)]
        public int RowVersion { getinternal set; }
 
        public virtual void Validate(VerifierResultCollection validationErrors)
        {
        }
 
        [BeforeSet]
        internal void RemoveWhiteSpace(IEntityPropertySetInterceptorArgs args)
        {
            if (args.EntityProperty.DataType != typeof(string) || args.Value ==  null)
                return;
 
            args.Value = ((string) args.Value).Trim();
        }
    }
Back to Top
Vonzkie View Drop Down
Senior Member
Senior Member
Avatar

Joined: 01-Aug-2011
Location: PH
Posts: 133
Post Options Post Options   Quote Vonzkie Quote  Post ReplyReply Direct Link To This Post Posted: 15-Aug-2012 at 8:38pm
Hi,

Thanks for the reply.

However we can't just simply convert our models to code first since our application are already up and running in the market.
So we have no choice but to do this manually in the designer..

Regards,
Von
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 15-Aug-2012 at 10:10pm
That's the perfect time to switch to Code-First :-) Kidding aside, yes you have a choice. Our T4 can generate Code-First style entity classes. We call this Code-Second.
 
 
In fact that's how the Cocktail Reference Application evolved. It started with an edmx before DevForce had Code-First support, then got converted to Code-First using Code-Second and finally refactored into what you see today. There's work involved in converting to a clean Code-First model, but the T4 gives you a good head start.
Back to Top
stephenmcd1 View Drop Down
DevForce MVP
DevForce MVP


Joined: 27-Oct-2009
Location: Los Angeles, CA
Posts: 166
Post Options Post Options   Quote stephenmcd1 Quote  Post ReplyReply Direct Link To This Post Posted: 16-Aug-2012 at 10:09am
Originally posted by Vonzkie

So we have no choice but to do this manually in the designer..

Don't forget that the designer is just a really fancy XML editor.  I've had times where I need to make lots of very similar changes and it was pretty easy using just a text editor and find/replace.  For example, in our app we have a column called Timestamp on almost every entity that is our concurrency column.  In the EDMX, there is a row like this under all our entities:
<Property Name="Timestamp" Type="Binary" Nullable="false" MaxLength="8" FixedLength="true" />
To add concurrency to all those properties we just did a search for that text and replaced it with this:
<Property Name="Timestamp" Type="Binary" Nullable="false" MaxLength="8" FixedLength="true" annotation:StoreGeneratedPattern="Computed" ib10:ConcurrencyStrategy="Client" ConcurrencyMode="Fixed" />
In no time, we added concurrency to hundreds of entities.  Of course, this is a one-time thing so for any new entities added to the model, you need to remember to set the concurrency.  But at least it saves time the first time. 

Note: Obviously you're case is a bit different - your column is called intConcurrencyID instead of Timestamp and you might want different options.  But if you just setup one property how you want it to look, you can then see what XML got generated for it and use that as a basis for the search/replace.

Hope that helps!

-Stephen
Back to Top
Vonzkie View Drop Down
Senior Member
Senior Member
Avatar

Joined: 01-Aug-2011
Location: PH
Posts: 133
Post Options Post Options   Quote Vonzkie Quote  Post ReplyReply Direct Link To This Post Posted: 16-Aug-2012 at 4:07pm
THanks guys for all the inputs. I'm gonna take note of using Code Second and this find-replace approach :)
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down