Получение фасетов сущностей и других метаданных во время выполнения

У меня есть приложение .NET 4.0 WinForms, и я использую Entity Framework 5 с подходом Model First. В VS EF Designer я создал дюжину или около того сущностей с множеством скалярных свойств типа String, а затем на панели свойств настроил параметры (например, общие параметры, фасеты Параметры) для них, чтобы соответствовать требованиям БД.

На уровне BL я могу проверить объект объекта, чтобы проверить, содержит ли он правильные значения, например, с помощью метода DbContext.Entry(Of T)(entity).GetValidationResult(). Но мне нужно разработать также проверку полей ввода слоя графического интерфейса для WinForms. Я хотел бы реализовать динамическую проверку GUI, основанную на значениях метаданных свойств набора сущностей, синхронизировать проверку BL с проверкой GUI и избежать избыточности написанного исходного кода.

Мой вопрос: как я могу получить значения метаданных, в частности значения метаданных фасетов (например, Фиксированная длина, Максимальная длина, Обнуляемый) автоматически сгенерированных сущности во время выполнения?

Насколько я знаю, есть возможность использовать аннотации данных на основе атрибутов свойств в созданном вручную частичном классе. Однако в подходе Model First это решение может также включать проблемы избыточности и проблемы синхронизации с метаданными из панели инструментов и базы данных VS EF Designer Properties.


person sgnsajgon    schedule 09.04.2013    source источник


Ответы (1)


Это должно помочь вам начать работу, но вам нужно перейти к отладчику и специально протестировать, чтобы получить то, что вам нужно...

Пример кода...

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;
}

Но это только часть истории.

Я понял, что в некоторых случаях это работает (поэтому вам нужно немного поэкспериментировать) в зависимости от того, что вам нужно. Но у вас также есть other spaces - например. SSpace. Так, например. для имен таблиц это работает лучше...

var ssSpaceSet = objectContext.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.SSpace).First()
    .BaseEntitySets
    .First(meta => meta.ElementType.Name == "YourTableName");

...а потом частная Table собственность.

В вашем случае вы должны получить большую часть информации там, но, например. созданный выше магазин не заполняется там, но, я думаю, в каком-то другом «пространстве» (подробнее об этом в одной из ссылок).

И взгляните на следующие ссылки:


Получить схему модели для программного создания базы данных с использованием поставщика, который не поддерживает CreateDatabase
Как программно читать метаданные EF DbContext?
Как проверить модульным тестом, что свойства помечены как вычисленные в модели ORM ?

person NSGaga-mostly-inactive    schedule 09.04.2013