Quantcast
Channel: Entity Framework
Viewing all articles
Browse latest Browse all 10318

New Post: ModelBuilder and extended MetadataProperties (DataModelAnnotation?)

$
0
0

 

I did some changes, I describe them here it as a proposals. Currently I only the made the changes required for annotation properties with arbitrary metadata. The following code is the modified ConfigurationBase class.

publicabstractclass ConfigurationBase
{private IDictionary<Tuple<string, string>, DataModelAnnotation> _arbitraryMetadata;public ConfigurationBase()
    {this._arbitraryMetadata = new Dictionary<Tuple<string, string>, DataModelAnnotation>();
    }publicvoid ArbitraryMetadata(string metadataNamespace, string metadataAttributeName, string value)
    {
        DebugCheck.NotEmpty(metadataNamespace);
        DebugCheck.NotEmpty(metadataAttributeName);this._arbitraryMetadata[Tuple.Create(metadataNamespace, metadataAttributeName)] =new DataModelAnnotation()
            {
                Namespace = metadataNamespace,
                Name = metadataAttributeName,
                Value = value
            };
    }internalvirtualvoid Configure(MetadataItem item)
    {
        DebugCheck.NotNull(item);if (_arbitraryMetadata.Values.Count > 0)
        {
            IList<DataModelAnnotation> arbitraryMetadata = item.Annotations.GetArbitraryMetadata();if (arbitraryMetadata == null)
            {
                arbitraryMetadata = new List<DataModelAnnotation>();
                item.Annotations.SetArbitraryMetadata(arbitraryMetadata);
            }foreach (DataModelAnnotation metadata in _arbitraryMetadata.Values)
            {
                arbitraryMetadata.Add(metadata);
            }
        }
    }
}

The Configure method is called by the configuration components (currently PrimitivePropertyConfiguration) derived from the ConfigurationBase class. The EdmSerializationVisitor was changed too. It adds the arbitrary metadata to the XML.

protectedoverridevoid VisitAnnotations(MetadataItem item, IEnumerable<DataModelAnnotation> annotations)
{var arbitraryAttributes = annotations.GetArbitraryMetadata();if (arbitraryAttributes != null)
    {foreach (DataModelAnnotation attribute in arbitraryAttributes)
        {
            _schemaWriter.WriteArbitraryAttribute(attribute);
        }
    }base.VisitAnnotations(item, annotations);
}

 These changes enabled to write custom conventions like the following:

publicclass MyConvention :
    AttributeConfigurationConvention<PropertyInfo, PrimitivePropertyConfiguration, MyMetadataAttribute>
{publicoverridevoid Apply(PropertyInfo memberInfo, PrimitivePropertyConfiguration configuration, MyMetadataAttribute attribute)
    {
        configuration.ArbitraryMetadata("http://example.org/2012/entity", "MyMetadata", attribute.Value);
    }
}

Unfortunately this does not push the configuration to the storage schema. To overcome this is issue I created another convention. However, I think some better solution should be used to achieve this.

publicclass MetadataInheritanceConvention : IDbConvention<MetadataItem>
{publicvoid Apply(MetadataItem dbDataModelItem, EdmModel model)
    {var conf = dbDataModelItem.Annotations.FirstOrDefault(a => a.Name == "Configuration");if (conf == null || !(conf.Value is ConfigurationBase))
        {return;
        }

        ((ConfigurationBase)conf.Value).Configure(dbDataModelItem);
    }
}

If the conventions are registered then the following entity definition adds the desired arbitrary metadata to the storage (and conceptual) schema.

publicclass Thing
{
    [Key]publicint Id { get; set; }

    [MyMetadata("value")]publicstring Data { get; set; }
}

The ADO.NET provider can see this in the appropriate MetadataProperties collection:

PropertyKind=Extended
Name="http://example.org/2012/entity:MyMetadata"
Value="value"
What do you think of this concept?

 


Viewing all articles
Browse latest Browse all 10318

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>