Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the maximum length of a string from an EDMX model in code?

I've created an EDMX object from a database I'm programming against.

I need to get input from a user and save it to a row in the database table. The problem is that I need to limit the length of input strings to the width of the corresponding VARCHAR column in the database.

When I browse the model, I can clearly see in the properties window that the model knows the max length of the string, but I don't know how to access this data in code.

If I want to write something like this:

Entities entities = new Entities();
myTable = entities.myTable.First();
if (userInput.length > myTable.columnA.MaxLength)
{
    // tell the user that the input is too long.
}
else
{
    myTable.columnA = userInput;
}

How do I write it?

Update: I would like to point out that the IObjectContextAdapater mentioned in the answers below is in the System.Data.Entity.Infrastructure namespace.

like image 845
Vivian River Avatar asked Nov 19 '14 18:11

Vivian River


2 Answers

Here are two methods by which you can read the meta data:

int? GetMaxLength(DbContext context, string tableName, string propertyName)
{
    var oc = ((IObjectContextAdapter)context).ObjectContext;

    return oc.MetadataWorkspace.GetItems(DataSpace.CSpace).OfType<EntityType>()
             .Where(et => et.Name == tableName)
             .SelectMany(et => et.Properties.Where(p => p.Name == propertyName))
             .Select (p => p.MaxLength)
             .FirstOrDefault();
}

int? GetMaxLength<T>(DbContext context, Expression<Func<T, object>> property)
{
    var memberExpression = (MemberExpression)property.Body;
    string propertyName = memberExpression.Member.Name;
    return GetMaxLength(context, typeof(T).Name, propertyName);
}

So you can either enter the table name and property name, or an expression that specifies the property you're interested in.

Another approach could be to create a MetaData class and use the MaxLength attribute.

like image 102
Gert Arnold Avatar answered Sep 24 '22 14:09

Gert Arnold


It's not very pretty; reading edmx properties at runtime is not something Microsoft exposed easily or documented well (or in some cases, at all). context is your DBContext.

var objectContext = ((IObjectContextAdapter)context).ObjectContext;
var entityType = objectContext.MetadataWorkspace.GetItems<EntityType>(DataSpace.CSpace).Where(e => e.Name == "your entity name").First();
var facets = entityType.Properties["your property name"].TypeUsage.Facets;

facets will look something like this, so you'll need to look for the MaxLength Name(may not exist, depending on the underlying field type) and get the Value:

Count = 5
    [0]: Nullable=false
    [1]: DefaultValue=null
    [2]: MaxLength=250
    [3]: Unicode=false
    [4]: FixedLength=false
like image 39
Paul Abbott Avatar answered Sep 23 '22 14:09

Paul Abbott