ADO.NET EntityObject Generator: how to get the EntityType’s EntitySet and how to get EntitySet’s EntityTypes?

One of my customers wanted to know how to get all EntityTypes for an EntitySet in his T4 template based on the MS ADO.NET EntityObject Generator one.


So I made a POC for him.


What do I do?


I change two classes included in the template (my changes are in bold):


private class EntitySetObjectSetPropertyWrapper : MetadataItemWrapper

{

    public EntitySetObjectSetPropertyWrapper(EntitySet entitySet, WrapperBase wrapper)

        : base(entitySet, wrapper)

    {

    }

    public new EntitySet Source { get { return (EntitySet)base.Source; } }

    public string ModelName { get { return Source.Name; } }

    public string PropertyName { get { return Escape(Source.Name); } }

    public string FieldName { get { return “_” + Source.Name; } }

    public string TypeName { get { return GetStructuralTypeName(Source.ElementType); } }

    public string GetterAccessibility { get { return GetAccessibility(Source, GETTER_ACCESS); } }

    public string NewModifier { get { return HasBaseMemberWithMatchingName(typeof(ObjectContext), Source.Name) ? “new “ : “”; } }

 

    public IEnumerable<EntityType> GetAllEntityTypes(ItemCollectionWrapper edm)

    {

        var entityType = Source.ElementType;

        yield return entityType;

        var entityTypeWrapper = edm.SourceEntities.First(e => e.Source == entityType);

        foreach (var subEntityType in entityTypeWrapper.SubEntityTypes(edm))

            yield return subEntityType;

    }

}

 

private class EntityTypeWrapper : StructuralTypeWrapper

{

    public EntityTypeWrapper(EntityType entity, WrapperBase wrapper)

        : base(entity, wrapper)

    {

    }

    public new EntityType Source { get { return (EntityType)base.Source; } }

 

    public string AbstractOption { get { return Source.Abstract ? “abstract “ : “”; } }

    public bool IsAbstract { get { return Source.Abstract; } }

    public string BaseTypeName { get { return Source.BaseType == null ? “EntityObject” : GetStructuralTypeName((StructuralType)Source.BaseType); } }

    public string TypeReferenceName { get { return GetStructuralTypeName(Source); } }

 

 

    public IEnumerable<NavigationPropertyWrapper> NavigationProperties { get { return Source.NavigationProperties.Where(n => n.DeclaringType == Source).Select(n => new NavigationPropertyWrapper(n, this)); } }

 

    public EntitySet GetEntitySet(ItemCollectionWrapper edm)

    {

        return edm.SourceEntityContainers.SelectMany(c => c.ObjectSetProperties).First(es => es.GetAllEntityTypes(edm).Contains(Source)).Source;

    }

    public IEnumerable<EntityType> SubEntityTypes(ItemCollectionWrapper edm, bool recursivity = true)

    {

        return edm.SourceEntities.Where(et => et.AllBaseEntityTypes.Contains(Source)).Select(et => et.Source);

    }

    public IEnumerable<EntityType> AllBaseEntityTypes

    {

        get { return GetBaseEntityTypes(Source); }

    }

    private static IEnumerable<EntityType> GetBaseEntityTypes(EntityType entityType)

    {

        EntityType baseType;

        if (entityType == null || (baseType = (EntityType)entityType.BaseType) == null)

            yield break;

        yield return baseType;

        foreach (var subEntityType in GetBaseEntityTypes(baseType))

            yield return subEntityType;

    }

}


Note that in your template, you probably don’t have the syntax colors.


Then you can use it in the rest of your template as I did in my POC:


/// <summary>
/// <#=set.SummaryComment#>
/// </summary><#=set.GetLongDescriptionComment(_regionIndentLevel)#>
/// <remarks>
/// Entity types:
<# foreach (var entityType in set.GetAllEntityTypes(Edm))
{ #>
///  <#= entityType.Name #>
<# } #>
/// </remarks>
<#=set.NewModifier#><#=set.GetterAccessibility#> ObjectSet<<#=set.TypeName#>> <#=set.PropertyName#>
{
     get
     {
         if ((<#=set.FieldName#> == null))
         {
             <#=set.FieldName#> = base.CreateObjectSet<<#=set.TypeName#>>(“<#=set.ModelName#>”);
         }
         return <#=set.FieldName#>;
     }
}


[…]


/// <summary>
/// <#=entity.SummaryComment#>
/// </summary><#=entity.GetLongDescriptionComment(_regionIndentLevel)#>
/// <remarks>EntitySet <#= entity.GetEntitySet(Edm).Name #></remarks>
[EdmEntityTypeAttribute(NamespaceName="<#=entity.ModelNamespace#>", Name="<#=entity.ModelName#>")]
[Serializable()]
[DataContractAttribute(IsReference=true)]
<#
        foreach(EntityTypeWrapper subType in Edm.GetAllDirectSubTypes(entity.Source))
        {
#>
[KnownTypeAttribute(typeof(<#=subType.TypeReferenceName#>))]
<#
        }
#>
<#=entity.TypeAccessibility#> <#=entity.AbstractOption#>partial class <#=entity.ClassName#> : <#=entity.BaseTypeName#>
{
<#
        if(!entity.IsAbstract)
        {
            WriteFactoryMethod(entity.FactoryMethodWrapper);
        }
        WritePrimitiveTypeProperties(entity, typeof(EntityObject));
        WriteComplexTypeProperties(entity, typeof(EntityObject));
#>


I profit by this post to thank Jeff.

This entry was posted in 10511, 7671, 7674, 7675. Bookmark the permalink.

5 Responses to ADO.NET EntityObject Generator: how to get the EntityType’s EntitySet and how to get EntitySet’s EntityTypes?

  1. sathiya says:

    Good articles

    Do you have any plan to write article about how to use Stopred procedure most articles only use tables and in my company accessing table is a crime.. thanks

  2. Matthieu MEZIL says:

    I hate stored procedures because, even if it’s interesting for the performance, I think that it’s a bad thing to split in two the business logic: your code and your stored procedure.
    However, I will try to write a post for it in the following days / weeks because I know that you aren’t alone to use it.

  3. lilikindsli says:

    pLe5HR I want to say – thank you for this!

  4. Do not enough money to buy a car? Do not worry, just because it’s available to receive the personal loans to resolve such kind of problems. Hence take a consolidation loan to buy all you want.

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>