none
Getting the value set by fluentapi, for example HasMaxLenght RRS feed

  • Question

  • I would need to obtain the value of the length of a string (in run-time) set by fluent api in EntityTypeConfiguration using for example:

    ...
    ...

    Property (p => p.ragione_so). HasMaxLenght (100);

    I would need to obtain, in example, the value 100.

    There 's a way to get it at  Run-time?

    thanks

    Tuesday, March 6, 2012 9:47 AM

Answers

  • The following will return the MaxValue. Please let me know if the following code works for you.

    using (var context = new TestEntities())
    {
        var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace.GetItems<EntityType>(DataSpace.CSpace);
        var entity = metadata.FirstOrDefault(i => i.Name == "Entity1");
        var member = entity.Members.FirstOrDefault(m => m.Name == "YourEntityString");
        var maxLength = member.TypeUsage.Facets.FirstOrDefault(f => f.Name == "MaxLength");
    
    }

    thank you,

    Julia


    This posting is provided "AS IS" with no warranties, and confers no rights.


    Wednesday, March 7, 2012 8:11 PM
    Moderator

All replies

  • I am not sure if you can get the facet value, but if you need it in order to perform validation before calling SaveChanges you can do the following:

    using (var context = new TestEntities())
    {
        Entity1 someEntity = new Entity1();
        someEntity.YourEntityString = "very long name .........";
    
        foreach (var property in new DbPropertyEntry[] { (context.Entry(someEntity).Property(p => p.YourEntityString)) })
        {
            foreach (var validationError in property.GetValidationErrors())
            {
                Console.WriteLine("{0} {1}", validationError.PropertyName, validationError.ErrorMessage);
                // handle validation errors...
    
            }
        }      
    }
    thank you,

    Julia


    This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, March 6, 2012 11:37 PM
    Moderator
  • Hi Julia, thanks for your reply, but i don't need it to Validate, i need it for create a dynamic form. I can read it if i set string lenght with data annotation but sometimes we need to custumize lenght with fluent api.

    You know if there is a way to read schema ?
    EF must read the schema for create the database...

    Thanks

    Wednesday, March 7, 2012 5:41 PM
  • hi,

    Interesting question. I never really need yet that but alrezdy wondered several times. It seems it uses the MetaDataWorkspace behing the scene (whihc make sense as code first likely just built EDM metadata at runtime so that you have the results as if you used an EDMX file).

    The MetadataWorkspace documentation is likely unusable but you should be able to quite quickly follow but looking at the implementation of the SQL Server Provider CreateDataScript implementation. It seems to see which type is used and get a MaxLength "facet". It would need some type to surface this in a more friendly way.

    An excerpt is :

    private void AppendType(EdmProperty column)
    {
        Facet facet;
        TypeUsage typeUsage = column.TypeUsage;
        bool flag = false;
        if ((((typeUsage.EdmType.Name == "binary") && (8 == typeUsage.GetMaxLength())) && (column.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", false, out facet) && (facet.Value != null))) && (StoreGeneratedPattern.Computed == ((StoreGeneratedPattern) facet.Value)))
        {
            flag = true;
            this.AppendIdentifier("rowversion");
        }
        else
        {
            string name = typeUsage.EdmType.Name;
            if ((typeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.PrimitiveType) && name.EndsWith("(max)", StringComparison.Ordinal))
            {
                this.AppendIdentifier(name.Substring(0, name.Length - "(max)".Length));
                this.AppendSql("(max)");
            }
            else
            {
                this.AppendIdentifier(name);
            }
            switch (typeUsage.EdmType.Name)
            {
                case "decimal":
                case "numeric":
                    this.AppendSqlInvariantFormat("({0}, {1})", new object[] { typeUsage.GetPrecision(), typeUsage.GetScale() });
                    goto Label_0242;
                case "datetime2":
                case "datetimeoffset":
                case "time":
                    this.AppendSqlInvariantFormat("({0})", new object[] { typeUsage.GetPrecision() });
                    goto Label_0242;
                case "binary":
                case "varbinary":
                case "nvarchar":
                case "varchar":
                case "char":
                case "nchar":
                    this.AppendSqlInvariantFormat("({0})", new object[] { typeUsage.GetMaxLength() });
                    goto Label_0242;
            }


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

    Wednesday, March 7, 2012 7:31 PM
  • The following will return the MaxValue. Please let me know if the following code works for you.

    using (var context = new TestEntities())
    {
        var metadata = ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace.GetItems<EntityType>(DataSpace.CSpace);
        var entity = metadata.FirstOrDefault(i => i.Name == "Entity1");
        var member = entity.Members.FirstOrDefault(m => m.Name == "YourEntityString");
        var maxLength = member.TypeUsage.Facets.FirstOrDefault(f => f.Name == "MaxLength");
    
    }

    thank you,

    Julia


    This posting is provided "AS IS" with no warranties, and confers no rights.


    Wednesday, March 7, 2012 8:11 PM
    Moderator
  • thanks Patrice for your reply... very interesting.
    Tuesday, March 13, 2012 9:38 AM
  • thanks Julia, looks good.
    Tuesday, March 13, 2012 9:39 AM