Skip to content

TVF returning EntityType unable to use Code-First #28

@09setht

Description

@09setht

If the Table-Valued Function returns an Entity Type, the DbContext will fail to deploy using Code-First. I found the root cause of this to be that the Types of the properties were CLR types (Int32, String, Guid, etc.) instead of SQL types (int, nvarchar, uniqueidentifier, etc.). More specifically, in the function called by test, the edmx under StorageModels looked like:

<RowType>
	<Property Name="BusinessEntityID" Type="Int32" Nullable="false" p10:StoreGeneratedPattern="Identity" xmlns:p10="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
	<Property Name="Title" Type="String" MaxLength="8" FixedLength="false" Unicode="true" Nullable="true" />
	<Property Name="FirstName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" Nullable="true" />
	<Property Name="LastName" Type="String" MaxLength="50" FixedLength="false" Unicode="true" Nullable="true" />
</RowType>

but should be:

<RowType>
	<Property Name="BusinessEntityID" Type="int" Nullable="false" p10:StoreGeneratedPattern="Identity" xmlns:p10="http://schemas.microsoft.com/ado/2009/02/edm/annotation" />
	<Property Name="Title" Type="nvarchar" MaxLength="8" FixedLength="false" Unicode="true" Nullable="true" />
	<Property Name="FirstName" Type="nvarchar" MaxLength="50" FixedLength="false" Unicode="true" Nullable="true" />
	<Property Name="LastName" Type="nvarchar" MaxLength="50" FixedLength="false" Unicode="true" Nullable="true" />
</RowType>

A fix I found for this was to change this section of Function.GetStoreReturnParameters in Function.DbModel.cs from:

storeReturnParameterRowType = RowType.Create(
             modelReturnParameterEntityType.Properties.Select(property => property.Clone()), null);

to:

storeReturnParameterRowType = RowType.Create(
               modelReturnParameterEntityType.Properties.Select(property =>
                                {
                                    var typeUsage = TypeUsage.Create(model.ProviderManifest.GetStoreType(property.TypeUsage).EdmType, property.TypeUsage.Facets);
                                    var result = EdmProperty.Create(property.Name, typeUsage);
                                    var propertyNames = new[] { nameof(EdmProperty.Name), nameof(EdmProperty.TypeUsage), nameof(EdmProperty.MetadataProperties) };
                                    result.SetMetadataProperties(property.MetadataProperties.Where(m => !propertyNames.Contains(m.Name)));
                                    return result;
                                }),
                            null);

Using this edit, I was able to produced the expected edmx. Overall, I have noticed that all the tests for this project are written against a database loaded from file rather than one generated when running the tests. This seems to be a limitation when testing the application of this library.

@Dixin would you be able to verify and integrate this change? Also, would you consider testing the use
of Code-First deployment with this library?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions