I have .NET 4.0 WinForms Application, and I use Entity Framework 5 with Model First Approach. In VS EF Designer, I have created a dozen or so entities with a lot of scalar properties of String
type, then in Properties Toolbar I have configured parameters (i.e. General parameters, Facets Parameters) for them, to fit DB requirements.
In BL layer I am able to validate entity object in purpose to check whether it contains correct values, for example by using DbContext.Entry(Of T)(entity).GetValidationResult()
method. But I need to develop also GUI layer input fields validation for WinForms. I would like to implement dynamic GUI validation, based on metadata values of entity set properties, to have BL validation synchronized with GUI validation, and to avoid redundancy of source code written.
My question is: How can I get metadata values, particularly facets metadata values (i.e. Fixed Length, Max Length, Nullable) of auto-generated entities on runtime?
As I know, there is a possibility to take advantage of data annotations based on properties attributes in manually created partial class. However, in Model First approach, this solution may also involve redundancy issues and synchronization problems with metadata from VS EF Designer Properties Toolbar and Database.
This should help you get started, but you'd need to get to debugger and test specifically to get what you need...
A sample code...
using (var db = new MyContext())
{
var objectContext = ((IObjectContextAdapter)db).ObjectContext;
var baseset = objectContext
.MetadataWorkspace
.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace)
.BaseEntitySets
.First(meta => meta.ElementType.Name == "YourEntityClassName");
var elementType = objectContext
.MetadataWorkspace
.GetEntityContainer(objectContext.DefaultContainerName, DataSpace.CSpace)
.BaseEntitySets
.First(meta => meta.ElementType.Name == "YourEntityClassName")
.ElementType;
EdmMember member = elementType.Members[2];
Facet item;
// if (member.TypeUsage.Facets.TryGetValue(EdmProviderManifest.StoreGeneratedPatternFacetName, false, out item))
if (member.TypeUsage.Facets.TryGetValue("StoreGeneratedPattern", false, out item))
{
var value = ((StoreGeneratedPattern)item.Value) == StoreGeneratedPattern.Computed;
}
But that's just part of the story.
What I realized is that's working in some cases (thus you need to experiment a bit) depending on what you need. But you also have other spaces
in there - e.g. the SSpace
. So e.g. for table names this works better...
var ssSpaceSet = objectContext.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.SSpace).First()
.BaseEntitySets
.First(meta => meta.ElementType.Name == "YourTableName");
...and then private Table
property.
In your case you should most info in there - but e.g. the above store generated is not populated there - but in some other 'space' I guess (more in one of the links on that).
And take a look at the following links:
Get Model schema to programmatically create database using a provider that doesn't support CreateDatabase
How I can read EF DbContext metadata programmatically?
How check by unit test that properties mark as computed in ORM model?