Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Abonnements

ADO.NET EntityObject Generator : comment récupérer l’EntitySet d’un EntityType et comment récupérer les EntityTypes d’un EntitySet ?

On m’a récemment posé la question  suivante : comment dans les templates T4 d’EF récupérer l’EntitySet d’un EntityType et comment récupérer les EntityTypes d’un EntitySet ?.

J’ai donc réalisé un petit POC pour cela.

J’ai pour cela changé deux classes incluses dans le template :

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;

    }

}

A noter que dans l’édition de votre template, vous n’avez probablement pas les couleurs syntaxiques.

Vous pouvez maintenant utiliser ces nouvelles méthodes dans votre template comme je l’ai fait dans mon 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));
#>

J’en profite pour remercier Jeff Reed de l’EF team qui m’a confirmé que mon approche était bien la bonne et Julien qui m’a récupéré le template public.

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Publié jeudi 3 septembre 2009 11:51 par Matthieu MEZIL

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Emportez votre sélection de la MSDN dans la poche ? par Blog de Jérémy Jeanson le il y a 16 heures et 46 minutes

- [ #Office365 ] Pb de connexion du flux Yammer ajouté à un site SharePoint par Le blog de Patrick [MVP SharePoint] le il y a 22 heures et 7 minutes

- NFluent & Data Annotations : coder ses propres assertions par Fathi Bellahcene le il y a 22 heures et 16 minutes

- Installer un site ASP.net 32bits sur un serveur exécutant SharePoint 2013 par Blog de Jérémy Jeanson le 04-17-2014, 06:34

- [ SharePoint Summit 2014 ] Tests de montée en charge SharePoint par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 20:44

- [ SharePoint Summit 2014 ] Bâtir un site web public avec Office 365 par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 18:30

- Kinect + Speech Recognition + Eedomus = Dommy par Aurélien GALTIER le 04-16-2014, 17:17

- [ SharePoint Summit 2014 ] Une méthodologie simple pour concevoir vos applications OOTB SharePoint de A à Z par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 16:51

- //Lean/ - Apprendre à faire des Apps Windows universelles par Blog de Jérémy Jeanson le 04-16-2014, 12:57

- Une culture de la donnée pour tous… par Le blog de Patrick [MVP SharePoint] le 04-16-2014, 11:00