luigi
luigi

Reputation: 13

Entity Framework 6 - Field conditional mapping

I am using Entity Framework for mapping our company software' and what i would like create a sort of conditional field mapping based on some field attributes i have created. Trying to better explain: I have created the attribute ModelPersistentAttribute that I use in the following way:

    [ModelPersistent("WORKORDER", persistentSchema: "mySchema", fromVersion:       "0.0", toVersion: "2.0")]
    public class WorkOrderDTO : AMOSEntityDTO
    {
     public WorkOrderDTO()
     { }

     public WorkOrderDTO(decimal WORKORDERID, string WONO, DateTime    LASTUPDATED)
     {
       this.WORKORDERID = WORKORDERID;
       this.WONO = WONO;
       this.LASTUPDATED = LASTUPDATED;
     }

     [Key]
     public decimal WORKORDERID { get; set; }

     public string WONO { get; set; }

     [ModelPersistentAttribute(persistentName: "TITLE", fromVersion:"0.0")]
     public string myTITLE { get; set; }
   }

Then I created a mapping class that has an automap method which is the following

    /// <summary>
    /// Automapping
    /// </summary>
    /// <param name="configurationOptions"></param>
    protected void AutoMap(EntityTypeMapCondigurationOptionsEFNet<TEntity> entityConfigurationOptions)
    {
        IEnumerable<ModelPersistentAttribute> persistentAttributes = typeof(TEntity).GetCustomAttributes<ModelPersistentAttribute>();
        if (persistentAttributes.Count() == 0 || persistentAttributes.Any(mpa => mpa.IsInRange(entityConfigurationOptions.Version, entityConfigurationOptions.DBMSType)))
        {
            if (persistentAttributes.Count() != 0) MapEntity(entityConfigurationOptions, persistentAttributes);
            foreach (var prop in typeof(TEntity).GetProperties())
            {
                NotMappedAttribute notMapped = prop.GetCustomAttribute<NotMappedAttribute>();
                if (notMapped == null)
                {
                    IEnumerable<ModelPersistentAttribute> modelAttributes = prop.GetCustomAttributes<ModelPersistentAttribute>();
                    if (modelAttributes.Count() == 0 || (modelAttributes.Any(ma => ma.IsInRange(entityConfigurationOptions.Version))))
                        MapProperty(prop, entityConfigurationOptions, modelAttributes);
                    else
                        IgnoreProperty(prop, entityConfigurationOptions);
                }
            }
        }
        else
            IgnoreEntity(entityConfigurationOptions);
    }

Everything seems to work properly for mapping

    protected virtual void MapProperty(PropertyInfo propertyInfo, EntityTypeMapCondigurationOptionsEFNet<TEntity> entityConfigurationOptions, IEnumerable<ModelPersistentAttribute> modelAttributes)
    {
        ModelPersistentAttribute modelVersionAttribute = modelAttributes.FirstOrDefault<ModelPersistentAttribute>(mpa => mpa.IsInRange(entityConfigurationOptions.Version, entityConfigurationOptions.DBMSType));
        string persistentName = string.Empty;
        if (modelVersionAttribute != null)
            persistentName = modelVersionAttribute.PersistentName;
        else
            persistentName = propertyInfo.Name;
        entityConfigurationOptions.ModelBuilder.Properties().Where(p => p.Equals(propertyInfo)).Configure(c=> c.HasColumnName(persistentName));
    }

but I am not able to run it when i want to ignore a property:

    /// <summary>
    /// Ignore property
    /// </summary>
    /// <param name="propertyInfo"></param>
    protected virtual void IgnoreProperty(PropertyInfo propertyInfo, EntityTypeMapCondigurationOptionsEFNet<TEntity> entityConfigurationOptions)
    {
        entityConfigurationOptions.ModelBuilder.Types<TEntity>().Configure(ctc => ctc.Ignore(p => propertyInfo));

 // The following as well doesn't work
 //entityConfigurationOptions.ModelBuilder.Types<TEntity>//().Configure(ctc =>    ctc.Ignore(p => propertyInfo.Name));

    }

The meaning of the error I get is something that I understand but I don't know how to solve:

The expression 'p => value(DTO.Service.EFCore.EntityTypeVersionMap`1+<>c__DisplayClass4_0[TestDTO.Shared.WorkOrderDTO]).propertyInfo' is not a valid property expression. The expression should represent a property: C#: 't => t.MyProperty' VB.Net: 'Function(t) t.MyProperty'.'

Any help on this will be VERY appreciated! Thanks in advance Luigi

Upvotes: 1

Views: 1101

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205729

You can use the non generic Types method with Where, which Configure -> Ignore method has overloads for string propertyName and PropertyInfo propertyInfo (the one that you need):

entityConfigurationOptions.ModelBuilder
    .Types().Where(type => type == typeof(TEntity))
    .Configure(ctc => ctc.Ignore(propertyInfo));

Upvotes: 1

Related Questions