C# 如何提取EF4实体上属性的数据库表和列名?

C# 如何提取EF4实体上属性的数据库表和列名?,c#,sql-server,entity-framework,entity-framework-4,C#,Sql Server,Entity Framework,Entity Framework 4,我正在为一个使用EF4作为数据访问层的应用程序编写一个审计组件。我能够非常轻松地确定修改了哪些实体,通过ObjectStateEntry对象,我可以提取修改过的原始值、当前值、实体名称和属性名称,但我还想提取SQL Server中使用的原始表名和列名(因为它们并不总是与模型的实体和属性名称匹配) 有人知道这样做的好方法吗?有可能吗?映射显然存储在MSL中,但我无法找到一种通过编程方式访问这些映射的方法。我有点困惑,为什么SQL Server中使用的原始表名和列名与模型的实体名和属性名不匹配。除了

我正在为一个使用EF4作为数据访问层的应用程序编写一个审计组件。我能够非常轻松地确定修改了哪些实体,通过ObjectStateEntry对象,我可以提取修改过的原始值、当前值、实体名称和属性名称,但我还想提取SQL Server中使用的原始表名和列名(因为它们并不总是与模型的实体和属性名称匹配)


有人知道这样做的好方法吗?有可能吗?映射显然存储在MSL中,但我无法找到一种通过编程方式访问这些映射的方法。

我有点困惑,为什么SQL Server中使用的原始表名和列名与模型的实体名和属性名不匹配。除了表us要提供多对多映射,对象名/属性与表名和列名之间(通常)应该有直接的对应关系


也就是说,实体框架是一个ORM。框架的全部目的是为数据库提供一个面向对象的视图,并抽象出必须直接与关系数据库交互的内容。EF并不是真正允许您绕过框架,据我所知,您希望做的事是不可能的。(但是,如果我错了,这是我今天学到的新东西,我将相应地删除或编辑此答案。)

如果您编写代码来审核映射,您不是真的在审核/验证Microsoft的EF代码吗?也许这可以安全地从问题域中定义出来,除非审核的目的是建立对EF本身的信任


但是如果你真的需要进行这种审计,一种可能是添加一个构建步骤,将.edmx文件作为一种资源嵌入到你正在检查的DLL中。你没有说你在测试的DLL上是否有这种控制/输入。不过,这可能是一种黑客行为——正如贾斯卡夫所说,ORMs的目的就是让你所做的完全符合你的意图不需要选择。

所有模型数据都可以通过此方法获得
myObjectContext.MetadataWorkspace.GetEntityContainer(myObjectContext.DefaultContainerName,DataSpace.CSSpace);


这至少应该给你一个如何做你想做的事情的开始。
DataSpace.CSSpace
指定概念名称和商店名称之间的映射。
DataSpace.CSSpace
给你概念模型,而
DataSpace.SSpace
给你存储模型。

浏览实体框架模型d后我看到它使用
EdmEntityTypeAttribute
DataMemberAttribute
来修饰生成的类和属性。每个类和属性都有一个
Name
属性,其中包含映射实体的名称(分别为表和列)。当属性名称与列的名称匹配时,设计器不会为位置参数
name
提供值。 下面的代码对我来说很好

 private static string GetTableName<T>() where T : EntityObject
    {
        Type type = typeof(T);
        var at = GetAttribute<EdmEntityTypeAttribute>(type);
        return at.Name;
    }

    private static string GetColumnName<T>(Expression<Func<T, object>> propertySelector) where T : EntityObject
    {
        Contract.Requires(propertySelector != null, "propertySelector is null.");

        PropertyInfo propertyInfo = GetPropertyInfo(propertySelector.Body);
        DataMemberAttribute attribute = GetAttribute<DataMemberAttribute>(propertyInfo);
        if (String.IsNullOrEmpty(attribute.Name))
        {
            return propertyInfo.Name;
        }
        return attribute.Name;
    }

    private static T GetAttribute<T>(MemberInfo memberInfo) where T : class
    {
        Contract.Requires(memberInfo != null, "memberInfo is null.");
        Contract.Ensures(Contract.Result<T>() != null);

        object[] customAttributes = memberInfo.GetCustomAttributes(typeof(T), false);
        T attribute = customAttributes.Where(a => a is T).First() as T;
        return attribute;
    }

    private static PropertyInfo GetPropertyInfo(Expression propertySelector)
    {
        Contract.Requires(propertySelector != null, "propertySelector is null.");
        MemberExpression memberExpression = propertySelector as MemberExpression;
        if (memberExpression == null)
        {
            UnaryExpression unaryExpression = propertySelector as UnaryExpression;
            if (unaryExpression != null && unaryExpression.NodeType == ExpressionType.Convert)
            {
                memberExpression = unaryExpression.Operand as MemberExpression;
            }
        }
        if (memberExpression != null && memberExpression.Member.MemberType == MemberTypes.Property)
        {
            return memberExpression.Member as PropertyInfo;
        }
        throw new ArgumentException("No property reference was found.", "propertySelector");
    }

    // Invocation example
    private static Test()
    {
         string table = GetTableName<User>();
         string column = GetColumnName<User>(u=>u.Name);
    }
private静态字符串GetTableName(),其中T:EntityObject
{
类型=类型(T);
var at=GetAttribute(类型);
返回.Name;
}
私有静态字符串GetColumnName(表达式属性选择器),其中T:EntityObject
{
Contract.Requires(propertySelector!=null,“propertySelector为null”);
PropertyInfo PropertyInfo=GetPropertyInfo(propertySelector.Body);
DataMemberAttribute=GetAttribute(propertyInfo);
if(String.IsNullOrEmpty(attribute.Name))
{
返回propertyInfo.Name;
}
返回属性.Name;
}
私有静态T GetAttribute(MemberInfo MemberInfo),其中T:class
{
Contract.Requires(memberInfo!=null,“memberInfo为null”);
Contract.sure(Contract.Result()!=null);
object[]customAttributes=memberInfo.GetCustomAttributes(typeof(T),false);
T attribute=customAttributes.Where(a=>a是T).First()作为T;
返回属性;
}
私有静态属性Info GetPropertyInfo(表达式属性选择器)
{
Contract.Requires(propertySelector!=null,“propertySelector为null”);
MemberExpression MemberExpression=propertySelector作为MemberExpression;
if(memberExpression==null)
{
UnaryExpression UnaryExpression=属性选择器为UnaryExpression;
if(unaryExpression!=null&&unaryExpression.NodeType==ExpressionType.Convert)
{
memberExpression=unaryExpression。操作数作为memberExpression;
}
}
if(memberExpression!=null&&memberExpression.Member.MemberType==MemberTypes.Property)
{
返回memberExpression.Member作为PropertyInfo;
}
抛出新ArgumentException(“未找到属性引用。”,“propertySelector”);
}
//调用示例
专用静态测试()
{
string table=GetTableName();
string column=GetColumnName(u=>u.Name);
}
这是一个用Visual Basic 2010编写的用于在概念信息和存储信息之间转换的通用算法。

我编写了一个新例程,用于将实体/属性对转换为表/列对。此类MSLMappingAction在其构造函数中接受模型名和XElement XML树、MSL映射文件或XML字符串。然后使用ConceptualToStore方法接受指定实体和属性“表达式”的字符串(存储在MSLConceptualInfo结构中)并查找表名和列名(存储在MSLStoreInfo结构中)

注意事项:

Option Infer On
Imports System.Xml.Linq

''' <summary>
''' This class allows one to convert between an EF conceptual model's entity/property pair
''' and its database store's table/column pair.
''' </summary>
''' <remarks>It takes into account entity splitting and complex-property designations;
''' it DOES NOT take into account inherited properties
''' (in such a case, you should access the entity's base class)</remarks>
Public Class MSLMappingAction

'   private fields and routines
Private mmaMSLMapping As XElement
Private mmaModelName, mmaNamespace As String

Private Function FullElementName(ByVal ElementName As String) As String
'   pre-pend Namespace to ElementName
Return "{" & mmaNamespace & "}" & ElementName
End Function

Private Sub ValidateParams(ByVal MappingXML As XElement, Byval ModelName As String)
'   verify that model name is specified
If String.IsNullOrEmpty(ModelName) Then
    Throw New EntityException("Entity model name is not given!")
End If
'   verify that we're using C-S space
If MappingXML.@Space <> "C-S" Then
    Throw New MetadataException("XML is not C-S mapping data!")
End If
'   get Namespace and set private variables
mmaNamespace = MappingXML.@xmlns
mmaMSLMapping = MappingXML : mmaModelName = ModelName
End Sub

Private Function IsSequenceEmpty(Items As IEnumerable(Of XElement)) As Boolean
'   determine if query result is empty
Return _
    Items Is Nothing OrElse Items.Count = 0
End Function

'   properties
''' <summary>
''' Name of conceptual entity model
''' </summary>
''' <returns>Conceptual-model String</returns>
''' <remarks>Model name can only be set in constructor</remarks>
Public ReadOnly Property EntityModelName() As String
Get
    Return mmaModelName
End Get
End Property

''' <summary>
''' Name of mapping namespace
''' </summary>
''' <returns>Namespace String of C-S mapping layer</returns>
''' <remarks>This value is determined when the XML mapping
''' is first parsed in the constructor</remarks>
Public ReadOnly Property MappingNamespace() As String
Get
    Return mmaNamespace
End Get
End Property

'   constructors
''' <summary>
''' Get C-S mapping information for an entity model (with XML tree)
''' </summary>
''' <param name="MappingXML">XML mapping tree</param>
''' <param name="ModelName">Conceptual-model name</param>
''' <remarks></remarks>
Public Sub New(ByVal MappingXML As XElement, ByVal ModelName As String)
ValidateParams(MappingXML, ModelName)
End Sub

''' <summary>
''' Get C-S mapping information for an entity model (with XML file)
''' </summary>
''' <param name="MSLFile">MSL mapping file</param>
''' <param name="ModelName">Conceptual-model name</param>
''' <remarks></remarks>
Public Sub New(ByVal MSLFile As String, ByVal ModelName As String)
Dim MappingXML As XElement = XElement.Load(MSLFile)
ValidateParams(MappingXML, ModelName)
End Sub

'   methods
''' <summary>
''' Get C-S mapping infomration for an entity model (with XML String)
''' </summary>
''' <param name="XMLString">XML mapping String</param>
''' <param name="ModelName">Conceptual-model name</param>
''' <returns></returns>
Public Shared Function Parse(ByVal XMLString As String, ByVal ModelName As String)
Return New MSLMappingAction(XElement.Parse(XMLString), ModelName)
End Function

''' <summary>
''' Convert conceptual entity/property information into store table/column information
''' </summary>
''' <param name="ConceptualInfo">Conceptual-model data
''' (.EntityName = entity expression String, .PropertyName = property expression String)</param>
''' <returns>Store data (.TableName = table-name String, .ColumnName = column-name String)</returns>
''' <remarks></remarks>
Public Function ConceptualToStore(ByVal ConceptualInfo As MSLConceptualInfo) As MSLStoreInfo
Dim StoreInfo As New MSLStoreInfo
With ConceptualInfo
    '   prepare to query XML
    If Not .EntityName.Contains(".") Then
        '   make sure entity name is fully qualified
        .EntityName = mmaModelName & "." & .EntityName
    End If
    '   separate property names if there's complex-type nesting
    Dim Properties() As String = .PropertyName.Split(".")
    '   get relevant entity mapping
    Dim MappingInfo As IEnumerable(Of XElement) = _                 
        (From mi In mmaMSLMapping.Descendants(FullElementName("EntityTypeMapping")) _
            Where mi.@TypeName = "IsTypeOf(" & .EntityName & ")" _
                OrElse mi.@TypeName = .EntityName _
         Select mi)
    '   make sure entity is in model
    If IsSequenceEmpty(MappingInfo) Then
        Throw New EntityException("Entity """ & .EntityName & """ was not found!")
    End If
    '   get mapping fragments
    Dim MappingFragments As IEnumerable(Of XElement) = _
        (From mf In MappingInfo.Descendants(FullElementName("MappingFragment")) _
         Select mf)
    '   make sure there's at least 1 fragment
    If IsSequenceEmpty(MappingFragments) Then
        Throw New EntityException("Entity """ & .EntityName & """ was not mapped!")
    End If
    '   search each mapping fragment for the desired property
    For Each MappingFragment In MappingFragments
        '   get physical table for this fragment
        StoreInfo.TableName = MappingFragment.@StoreEntitySet
        '   search property expression chain
        Dim PropertyMapping As IEnumerable(Of XElement) = {MappingFragment}
        '   parse complex property info (if any)
        For index = 0 To UBound(Properties) - 1
            '   go down 1 level
            Dim ComplexPropertyName = Properties(index)
            PropertyMapping = _
                (From pm In PropertyMapping.Elements(FullElementName("ComplexProperty")) _
                    Where pm.@Name = ComplexPropertyName)
            '   verify that the property specified for this level exists
            If IsSequenceEmpty(PropertyMapping) Then
                Exit For 'go to next fragment if not
            End If
        Next index
        '   property not found? try next fragment
        If IsSequenceEmpty(PropertyMapping) Then
            Continue For
        End If
        '   parse scalar property info
        Dim ScalarPropertyName = Properties(UBound(Properties))
        Dim ColumnName As String = _
            (From pm In PropertyMapping.Elements(FullElementName("ScalarProperty")) _
                Where pm.@Name = ScalarPropertyName _
                Select CN = pm.@ColumnName).FirstOrDefault
        '   verify that scalar property exists
        If Not String.IsNullOrEmpty(ColumnName) Then
            '   yes? return (exit) with column info
            StoreInfo.ColumnName = ColumnName : Return StoreInfo
        End If
    Next MappingFragment
    '   property wasn't found
    Throw New EntityException("Property """ & .PropertyName _
        & """ of entity """ & .EntityName & """ was not found!")
End With
End Function
End Class

''' <summary>
''' Conceptual-model entity and property information  
''' </summary>
Public Structure MSLConceptualInfo
''' <summary>
''' Name of entity in conceptual model
''' </summary>
''' <value>Entity expression String</value>
''' <remarks>EntityName may or may not be fully qualified (i.e., "ModelName.EntityName");
''' when a mapping method is called by the MSLMappingAction class, the conceptual model's
''' name and a period will be pre-pended if it's omitted</remarks>
Public Property EntityName As String
''' <summary>
''' Name of property in entity
''' </summary>
''' <value>Property expression String</value>
''' <remarks>PropertyName may be either a stand-alone scalar property or a scalar property
''' within 1 or more levels of complex-type properties; in the latter case, it MUST be fully
''' qualified (i.e., "ComplexPropertyName.InnerComplexPropertyName.ScalarPropertyName")</remarks>
Public Property PropertyName As String
End Structure

''' <summary>
''' Database-store table and column information
''' </summary>
Public Structure MSLStoreInfo
''' <summary>
''' Name of table in database
''' </summary>
Public Property TableName As String
''' <summary>
''' Name of column in database table
''' </summary>
Public Property ColumnName As String
End Structure
  • 还可以编写一个“storetoconcept”方法进行转换 另一个方向,但XML查询可能有点复杂 更复杂。
    Option Infer On
    Imports System.Xml.Linq
    
    ''' <summary>
    ''' This class allows one to convert between an EF conceptual model's entity/property pair
    ''' and its database store's table/column pair.
    ''' </summary>
    ''' <remarks>It takes into account entity splitting and complex-property designations;
    ''' it DOES NOT take into account inherited properties
    ''' (in such a case, you should access the entity's base class)</remarks>
    Public Class MSLMappingAction
    
    '   private fields and routines
    Private mmaMSLMapping As XElement
    Private mmaModelName, mmaNamespace As String
    
    Private Function FullElementName(ByVal ElementName As String) As String
    '   pre-pend Namespace to ElementName
    Return "{" & mmaNamespace & "}" & ElementName
    End Function
    
    Private Sub ValidateParams(ByVal MappingXML As XElement, Byval ModelName As String)
    '   verify that model name is specified
    If String.IsNullOrEmpty(ModelName) Then
        Throw New EntityException("Entity model name is not given!")
    End If
    '   verify that we're using C-S space
    If MappingXML.@Space <> "C-S" Then
        Throw New MetadataException("XML is not C-S mapping data!")
    End If
    '   get Namespace and set private variables
    mmaNamespace = MappingXML.@xmlns
    mmaMSLMapping = MappingXML : mmaModelName = ModelName
    End Sub
    
    Private Function IsSequenceEmpty(Items As IEnumerable(Of XElement)) As Boolean
    '   determine if query result is empty
    Return _
        Items Is Nothing OrElse Items.Count = 0
    End Function
    
    '   properties
    ''' <summary>
    ''' Name of conceptual entity model
    ''' </summary>
    ''' <returns>Conceptual-model String</returns>
    ''' <remarks>Model name can only be set in constructor</remarks>
    Public ReadOnly Property EntityModelName() As String
    Get
        Return mmaModelName
    End Get
    End Property
    
    ''' <summary>
    ''' Name of mapping namespace
    ''' </summary>
    ''' <returns>Namespace String of C-S mapping layer</returns>
    ''' <remarks>This value is determined when the XML mapping
    ''' is first parsed in the constructor</remarks>
    Public ReadOnly Property MappingNamespace() As String
    Get
        Return mmaNamespace
    End Get
    End Property
    
    '   constructors
    ''' <summary>
    ''' Get C-S mapping information for an entity model (with XML tree)
    ''' </summary>
    ''' <param name="MappingXML">XML mapping tree</param>
    ''' <param name="ModelName">Conceptual-model name</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal MappingXML As XElement, ByVal ModelName As String)
    ValidateParams(MappingXML, ModelName)
    End Sub
    
    ''' <summary>
    ''' Get C-S mapping information for an entity model (with XML file)
    ''' </summary>
    ''' <param name="MSLFile">MSL mapping file</param>
    ''' <param name="ModelName">Conceptual-model name</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal MSLFile As String, ByVal ModelName As String)
    Dim MappingXML As XElement = XElement.Load(MSLFile)
    ValidateParams(MappingXML, ModelName)
    End Sub
    
    '   methods
    ''' <summary>
    ''' Get C-S mapping infomration for an entity model (with XML String)
    ''' </summary>
    ''' <param name="XMLString">XML mapping String</param>
    ''' <param name="ModelName">Conceptual-model name</param>
    ''' <returns></returns>
    Public Shared Function Parse(ByVal XMLString As String, ByVal ModelName As String)
    Return New MSLMappingAction(XElement.Parse(XMLString), ModelName)
    End Function
    
    ''' <summary>
    ''' Convert conceptual entity/property information into store table/column information
    ''' </summary>
    ''' <param name="ConceptualInfo">Conceptual-model data
    ''' (.EntityName = entity expression String, .PropertyName = property expression String)</param>
    ''' <returns>Store data (.TableName = table-name String, .ColumnName = column-name String)</returns>
    ''' <remarks></remarks>
    Public Function ConceptualToStore(ByVal ConceptualInfo As MSLConceptualInfo) As MSLStoreInfo
    Dim StoreInfo As New MSLStoreInfo
    With ConceptualInfo
        '   prepare to query XML
        If Not .EntityName.Contains(".") Then
            '   make sure entity name is fully qualified
            .EntityName = mmaModelName & "." & .EntityName
        End If
        '   separate property names if there's complex-type nesting
        Dim Properties() As String = .PropertyName.Split(".")
        '   get relevant entity mapping
        Dim MappingInfo As IEnumerable(Of XElement) = _                 
            (From mi In mmaMSLMapping.Descendants(FullElementName("EntityTypeMapping")) _
                Where mi.@TypeName = "IsTypeOf(" & .EntityName & ")" _
                    OrElse mi.@TypeName = .EntityName _
             Select mi)
        '   make sure entity is in model
        If IsSequenceEmpty(MappingInfo) Then
            Throw New EntityException("Entity """ & .EntityName & """ was not found!")
        End If
        '   get mapping fragments
        Dim MappingFragments As IEnumerable(Of XElement) = _
            (From mf In MappingInfo.Descendants(FullElementName("MappingFragment")) _
             Select mf)
        '   make sure there's at least 1 fragment
        If IsSequenceEmpty(MappingFragments) Then
            Throw New EntityException("Entity """ & .EntityName & """ was not mapped!")
        End If
        '   search each mapping fragment for the desired property
        For Each MappingFragment In MappingFragments
            '   get physical table for this fragment
            StoreInfo.TableName = MappingFragment.@StoreEntitySet
            '   search property expression chain
            Dim PropertyMapping As IEnumerable(Of XElement) = {MappingFragment}
            '   parse complex property info (if any)
            For index = 0 To UBound(Properties) - 1
                '   go down 1 level
                Dim ComplexPropertyName = Properties(index)
                PropertyMapping = _
                    (From pm In PropertyMapping.Elements(FullElementName("ComplexProperty")) _
                        Where pm.@Name = ComplexPropertyName)
                '   verify that the property specified for this level exists
                If IsSequenceEmpty(PropertyMapping) Then
                    Exit For 'go to next fragment if not
                End If
            Next index
            '   property not found? try next fragment
            If IsSequenceEmpty(PropertyMapping) Then
                Continue For
            End If
            '   parse scalar property info
            Dim ScalarPropertyName = Properties(UBound(Properties))
            Dim ColumnName As String = _
                (From pm In PropertyMapping.Elements(FullElementName("ScalarProperty")) _
                    Where pm.@Name = ScalarPropertyName _
                    Select CN = pm.@ColumnName).FirstOrDefault
            '   verify that scalar property exists
            If Not String.IsNullOrEmpty(ColumnName) Then
                '   yes? return (exit) with column info
                StoreInfo.ColumnName = ColumnName : Return StoreInfo
            End If
        Next MappingFragment
        '   property wasn't found
        Throw New EntityException("Property """ & .PropertyName _
            & """ of entity """ & .EntityName & """ was not found!")
    End With
    End Function
    End Class
    
    ''' <summary>
    ''' Conceptual-model entity and property information  
    ''' </summary>
    Public Structure MSLConceptualInfo
    ''' <summary>
    ''' Name of entity in conceptual model
    ''' </summary>
    ''' <value>Entity expression String</value>
    ''' <remarks>EntityName may or may not be fully qualified (i.e., "ModelName.EntityName");
    ''' when a mapping method is called by the MSLMappingAction class, the conceptual model's
    ''' name and a period will be pre-pended if it's omitted</remarks>
    Public Property EntityName As String
    ''' <summary>
    ''' Name of property in entity
    ''' </summary>
    ''' <value>Property expression String</value>
    ''' <remarks>PropertyName may be either a stand-alone scalar property or a scalar property
    ''' within 1 or more levels of complex-type properties; in the latter case, it MUST be fully
    ''' qualified (i.e., "ComplexPropertyName.InnerComplexPropertyName.ScalarPropertyName")</remarks>
    Public Property PropertyName As String
    End Structure
    
    ''' <summary>
    ''' Database-store table and column information
    ''' </summary>
    Public Structure MSLStoreInfo
    ''' <summary>
    ''' Name of table in database
    ''' </summary>
    Public Property TableName As String
    ''' <summary>
    ''' Name of column in database table
    ''' </summary>
    Public Property ColumnName As String
    End Structure
    
    <?xml version="1.0" encoding="utf-8"?>
    <Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
      <EntityContainerMapping StorageEntityContainer="SCTModelStoreContainer" CdmEntityContainer="SocialContactsTracker">
        <EntitySetMapping Name="SocialContacts">
          <EntityTypeMapping TypeName="IsTypeOf(SCTModel.SocialContact)">
            <MappingFragment StoreEntitySet="SocialContacts">
              <ScalarProperty Name="Id" ColumnName="Id" />
              <ScalarProperty Name="DateAdded" ColumnName="DateAdded" />
              <ScalarProperty Name="Information" ColumnName="Information" />
              <ComplexProperty Name="DefaultAssociations" TypeName="SCTModel.DefaultAssociations">
                <ScalarProperty Name="DefaultLocationID" ColumnName="DefaultAssociations_DefaultLocationID" />
                <ScalarProperty Name="DefaultEmailID" ColumnName="DefaultAssociations_DefaultEmailID" />
                <ScalarProperty Name="DefaultPhoneNumberID" ColumnName="DefaultAssociations_DefaultPhoneNumberID" />
                <ScalarProperty Name="DefaultWebsiteID" ColumnName="DefaultAssociations_DefaultWebsiteID" />
              </ComplexProperty>
              <ScalarProperty Name="Picture" ColumnName="Picture" />
            </MappingFragment>
          </EntityTypeMapping>
          <EntityTypeMapping TypeName="IsTypeOf(SCTModel.Person)">
            <MappingFragment StoreEntitySet="SocialContacts_Person">
              <ScalarProperty Name="Id" ColumnName="Id" />
              <ScalarProperty Name="DateOfBirth" ColumnName="DateOfBirth" />
              <ScalarProperty Name="FirstName" ColumnName="FirstName" />
              <ScalarProperty Name="LastName" ColumnName="LastName" />
            </MappingFragment>
          </EntityTypeMapping>
          <EntityTypeMapping TypeName="IsTypeOf(SCTModel.Organization)">
            <MappingFragment StoreEntitySet="SocialContacts_Organization">
              <ScalarProperty Name="Id" ColumnName="Id" />
              <ScalarProperty Name="Name" ColumnName="Name" />
              <ScalarProperty Name="DateOfCreation" ColumnName="DateOfCreation" />
            </MappingFragment>
          </EntityTypeMapping>
        </EntitySetMapping>
        <EntitySetMapping Name="Locations">
          <EntityTypeMapping TypeName="IsTypeOf(SCTModel.Location)">
            <MappingFragment StoreEntitySet="Locations">
              <ScalarProperty Name="Id" ColumnName="Id" />
              <ScalarProperty Name="City" ColumnName="City" />
              <ScalarProperty Name="State" ColumnName="State" />
              <ScalarProperty Name="ZIP" ColumnName="ZIP" />
              <ScalarProperty Name="Country" ColumnName="Country" />
              <ComplexProperty Name="Address" TypeName="SCTModel.Address">
                <ScalarProperty Name="Street" ColumnName="Address_Street" />
                <ScalarProperty Name="Apartment" ColumnName="Address_Apartment" />
                <ScalarProperty Name="HouseNumber" ColumnName="Address_HouseNumber" />
              </ComplexProperty>
            </MappingFragment>
          </EntityTypeMapping>
        </EntitySetMapping>
        <EntitySetMapping Name="PhoneNumbers">
          <EntityTypeMapping TypeName="IsTypeOf(SCTModel.PhoneNumber)">
            <MappingFragment StoreEntitySet="PhoneNumbers">
              <ScalarProperty Name="Id" ColumnName="Id" />
              <ScalarProperty Name="Number" ColumnName="Number" />
              <ScalarProperty Name="PhoneType" ColumnName="PhoneType" />
            </MappingFragment>
          </EntityTypeMapping>
        </EntitySetMapping>
        <EntitySetMapping Name="Emails">
          <EntityTypeMapping TypeName="IsTypeOf(SCTModel.Email)">
            <MappingFragment StoreEntitySet="Emails">
              <ScalarProperty Name="Id" ColumnName="Id" />
              <ScalarProperty Name="DomainName" ColumnName="DomainName" />
              <ScalarProperty Name="UserName" ColumnName="UserName" />
            </MappingFragment>
          </EntityTypeMapping>
        </EntitySetMapping>
        <EntitySetMapping Name="Websites">
          <EntityTypeMapping TypeName="IsTypeOf(SCTModel.Website)">
            <MappingFragment StoreEntitySet="Websites">
              <ScalarProperty Name="Id" ColumnName="Id" />
              <ScalarProperty Name="URL" ColumnName="URL" />
            </MappingFragment>
          </EntityTypeMapping>
        </EntitySetMapping>
        <AssociationSetMapping Name="SocialContactWebsite" TypeName="SCTModel.SocialContactWebsite" StoreEntitySet="SocialContactWebsite">
          <EndProperty Name="SocialContact">
            <ScalarProperty Name="Id" ColumnName="SocialContacts_Id" />
          </EndProperty>
          <EndProperty Name="Website">
            <ScalarProperty Name="Id" ColumnName="Websites_Id" />
          </EndProperty>
        </AssociationSetMapping>
        <AssociationSetMapping Name="SocialContactPhoneNumber" TypeName="SCTModel.SocialContactPhoneNumber" StoreEntitySet="SocialContactPhoneNumber">
          <EndProperty Name="SocialContact">
            <ScalarProperty Name="Id" ColumnName="SocialContacts_Id" />
          </EndProperty>
          <EndProperty Name="PhoneNumber">
            <ScalarProperty Name="Id" ColumnName="PhoneNumbers_Id" />
          </EndProperty>
        </AssociationSetMapping>
        <AssociationSetMapping Name="SocialContactEmail" TypeName="SCTModel.SocialContactEmail" StoreEntitySet="SocialContactEmail">
          <EndProperty Name="SocialContact">
            <ScalarProperty Name="Id" ColumnName="SocialContacts_Id" />
          </EndProperty>
          <EndProperty Name="Email">
            <ScalarProperty Name="Id" ColumnName="Emails_Id" />
          </EndProperty>
        </AssociationSetMapping>
        <AssociationSetMapping Name="SocialContactLocation" TypeName="SCTModel.SocialContactLocation" StoreEntitySet="SocialContactLocation">
          <EndProperty Name="SocialContact">
            <ScalarProperty Name="Id" ColumnName="SocialContacts_Id" />
          </EndProperty>
          <EndProperty Name="Location">
            <ScalarProperty Name="Id" ColumnName="Locations_Id" />
          </EndProperty>
        </AssociationSetMapping>
      </EntityContainerMapping>
    </Mapping>