Click here to Skip to main content
15,936,802 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
I plan to add supplementary (unique) indexes to my entities' tables. Since I can't have more than one EF key for an entity, the other indexes need to be created using CONSTRAINT SQL, which in turns means converting between entity and property names (conceptual model) and table and column names (database store). I've taken the following code from another person (and converted it to VB):

Imports System.Data.Objects
Imports System.Data.Entity
Imports System.Data.SqlClient
Imports System.Data.EntityClient
Imports System.Data.Metadata.Edm
Imports System.Data.Objects.DataClasses
Imports System.Linq.Expressions
Imports System.Runtime.Serialization
Imports System.Reflection

Public Class ConvertConceptualToStore
    Private Shared Function GetTableName(Of T As EntityObject)() As String
    Dim type As Type = GetType(T)
    Dim at As EdmEntityTypeAttribute = GetAttribute(Of EdmEntityTypeAttribute)(type)
    Return at.Name
    End Function

    Private Shared Function GetColumnName(Of T As EntityObject) _
        (ByVal propertySelector As Expression(Of Func(Of T, Object))) As String

    If propertySelector Is Nothing Then
        Throw New Exception("""" & propertySelector.ToString & """ is null.")
    End If

    Dim propertyInfo As PropertyInfo = GetPropertyInfo(propertySelector.Body)
    Dim attribute As DataMemberAttribute = _
        GetAttribute(Of DataMemberAttribute)(propertyInfo)
    If String.IsNullOrEmpty(attribute.Name) Then
        Return propertyInfo.Name
        Return attribute.Name
    End If
    End Function

    Private Shared Function GetAttribute(Of T As Class)(ByVal memberInfo As MemberInfo) As T
    If memberInfo Is Nothing Then
        Throw New Exception("""" & memberInfo.ToString & """ is null.")
    End If

    Dim customAttributes() As Object = _
        memberInfo.GetCustomAttributes(GetType(T), False)
    Dim attribute As T = _
        DirectCast(customAttributes.Where(Function(a) TypeOf a Is T).First(), T)
    Return attribute
    End Function

    Private Shared Function GetPropertyInfo(ByVal propertySelector As Expression) As PropertyInfo
    If propertySelector Is Nothing Then
        Throw New Exception("""" & propertySelector.ToString & """ is null.")
    End If

    Dim memberExpression As MemberExpression = _
        TryCast(propertySelector, MemberExpression)
    If memberExpression Is Nothing Then
        Dim unaryExpression As UnaryExpression = _
            TryCast(propertySelector, UnaryExpression)
        If unaryExpression IsNot Nothing _
                AndAlso unaryExpression.NodeType = ExpressionType.Convert Then
            memberExpression = TryCast(unaryExpression.Operand, MemberExpression)
        End If
    End If
    If memberExpression IsNot Nothing _
            AndAlso memberExpression.Member.MemberType = MemberTypes.Property Then
        Return DirectCast(memberExpression.Member, PropertyInfo)
        Throw New ArgumentException("No property reference was found.", "propertySelector")
    End If
    End Function

    ' Invocation example
    Public Shared Sub Test()
    Dim table As String = GetTableName(Of Entity)()
    Dim column As String = GetColumnName(Of Entity)(Function(Entity) Entity.Property)
    End Sub
End Class

I need to know some things:

1. I don't need an ObjectContext for this code, do I?
2. What if the property I need to convert to a field is part of a
complex property? Do I need to augment or modify the code for such a
situation? (i.e., Suppose I have an entity called Location, with a
complex property of Address, and I need to get the field for
Address.Street. Do I just use,
columnName = GetColumnName(Of Location)(Function(Location) Location.Address.Street),
or do I have to do something more?)
3. Suppose my code doesn't know beforehand the names of my entity and
property. Is there a way to adapt this code to take a _String value_
for each (at least for the property name; i.e., "Entity.Property"), then find the
appropriate class/property reference therefrom?

Please answer these questions ASAP!
Updated 23-Jun-14 11:34am

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900