Skip to content
This repository was archived by the owner on Nov 29, 2017. It is now read-only.

Commit b9e6e44

Browse files
author
moozzyk
committed
At50% - opening mapping API part 2 - Function imports (limited)
1 parent 2706ea2 commit b9e6e44

15 files changed

+519
-19
lines changed

src/EntityFramework/Core/Mapping/FunctionImportMapping.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ namespace System.Data.Entity.Core.Mapping
88
/// <summary>
99
/// Represents a mapping from a model function import to a store composable or non-composable function.
1010
/// </summary>
11-
internal abstract class FunctionImportMapping
11+
public abstract class FunctionImportMapping
1212
{
1313
internal FunctionImportMapping(EdmFunction functionImport, EdmFunction targetFunction)
1414
{
15-
DebugCheck.NotNull(functionImport);
16-
DebugCheck.NotNull(targetFunction);
15+
Check.NotNull(functionImport, "functionImport");
16+
Check.NotNull(targetFunction, "targetFunction");
1717

1818
FunctionImport = functionImport;
1919
TargetFunction = targetFunction;
@@ -22,11 +22,11 @@ internal FunctionImportMapping(EdmFunction functionImport, EdmFunction targetFun
2222
/// <summary>
2323
/// Gets model function (or source of the mapping)
2424
/// </summary>
25-
internal readonly EdmFunction FunctionImport;
25+
public EdmFunction FunctionImport { get; private set; }
2626

2727
/// <summary>
2828
/// Gets store function (or target of the mapping)
2929
/// </summary>
30-
internal readonly EdmFunction TargetFunction;
30+
public EdmFunction TargetFunction { get; private set; }
3131
}
3232
}

src/EntityFramework/Core/Mapping/FunctionImportMappingComposable.cs

+50-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace System.Data.Entity.Core.Mapping
44
{
55
using System.Collections.Generic;
6+
using System.Collections.ObjectModel;
67
using System.Data.Entity.Core.Common;
78
using System.Data.Entity.Core.Common.CommandTrees;
89
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
@@ -11,6 +12,7 @@ namespace System.Data.Entity.Core.Mapping
1112
using System.Data.Entity.Core.Metadata.Edm;
1213
using System.Data.Entity.Core.Query.InternalTrees;
1314
using System.Data.Entity.Core.Query.PlanCompiler;
15+
using System.Data.Entity.Resources;
1416
using System.Data.Entity.Utilities;
1517
using System.Diagnostics;
1618
using System.Diagnostics.CodeAnalysis;
@@ -19,8 +21,46 @@ namespace System.Data.Entity.Core.Mapping
1921
/// <summary>
2022
/// Represents a mapping from a model function import to a store composable function.
2123
/// </summary>
22-
internal class FunctionImportMappingComposable : FunctionImportMapping
24+
public class FunctionImportMappingComposable : FunctionImportMapping
2325
{
26+
[SuppressMessage("Microsoft.Design", "CA1002:DoNotExposeGenericLists")]
27+
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
28+
public FunctionImportMappingComposable(
29+
EdmFunction functionImport,
30+
EdmFunction targetFunction,
31+
List<Tuple<StructuralType, List<StorageConditionPropertyMapping>, List<StoragePropertyMapping>>> structuralTypeMappings)
32+
: base(functionImport, targetFunction)
33+
{
34+
if (!functionImport.IsComposableAttribute)
35+
{
36+
throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("functionImport"));
37+
}
38+
39+
if (!targetFunction.IsComposableAttribute)
40+
{
41+
throw new ArgumentException(Strings.NonComposableFunctionCannotBeMappedAsComposable("targetFunction"));
42+
}
43+
44+
if (functionImport.EntitySet != null)
45+
{
46+
throw new NotSupportedException(Strings.ComposableFunctionImportsReturningEntitiesNotSupported);
47+
}
48+
49+
EdmType resultType;
50+
if (!MetadataHelper.TryGetFunctionImportReturnType(functionImport, 0, out resultType))
51+
{
52+
throw new ArgumentException(Strings.InvalidReturnTypeForComposableFunction);
53+
}
54+
55+
if (!TypeSemantics.IsScalarType(resultType)
56+
&& (structuralTypeMappings == null || structuralTypeMappings.Count == 0))
57+
{
58+
throw new ArgumentException(Strings.StructuralTypeMappingsMustNotBeNullForFunctionImportsReturingNonScalarValues);
59+
}
60+
61+
m_structuralTypeMappings = structuralTypeMappings;
62+
}
63+
2464
internal FunctionImportMappingComposable(
2565
EdmFunction functionImport,
2666
EdmFunction targetFunction,
@@ -80,11 +120,18 @@ private readonly List<Tuple<StructuralType, List<StorageConditionPropertyMapping
80120
/// </summary>
81121
private Node m_internalTreeNode;
82122

123+
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
124+
public ReadOnlyCollection<Tuple<StructuralType, List<StorageConditionPropertyMapping>, List<StoragePropertyMapping>>> StructuralTypeMappings
125+
{
126+
get { return m_structuralTypeMappings == null ? null : m_structuralTypeMappings.AsReadOnly(); }
127+
}
128+
83129
internal EdmProperty[] TvfKeys
84130
{
85131
get { return m_targetFunctionKeys; }
86132
}
87133

134+
[SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")]
88135
[SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "projectOp")]
89136
[SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters",
90137
MessageId = "System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(System.Boolean,System.String)")]
@@ -210,6 +257,8 @@ public override Node Visit(VarRefOp op, Node n)
210257

211258
internal DbQueryCommandTree GenerateFunctionView(out DiscriminatorMap discriminatorMap)
212259
{
260+
DebugCheck.NotNull(m_mappingItemCollection);
261+
213262
discriminatorMap = null;
214263

215264
// Prepare the direct call of the store function as StoreFunction(@EdmFunc_p1, ..., @EdmFunc_pN).

src/EntityFramework/Core/Mapping/StorageEntityContainerMapping.cs

+9-2
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,11 @@ public virtual IEnumerable<StorageAssociationSetMapping> AssociationSetMappings
177177
get { return RelationshipSetMaps.OfType<StorageAssociationSetMapping>(); }
178178
}
179179

180+
public ReadOnlyCollection<FunctionImportMapping> FunctionImportMappings
181+
{
182+
get { return m_functionImportMappings.Values.ToList().AsReadOnly(); }
183+
}
184+
180185
/// <summary>
181186
/// a list of all the entity set maps under this
182187
/// container. In CS mapping, the mapping is done
@@ -356,9 +361,11 @@ internal bool HasMappingFragments()
356361

357362
// Methods to modify and access function imports, which association a "functionImport" declared
358363
// in the model entity container with a targetFunction declared in the target
359-
internal void AddFunctionImportMapping(EdmFunction functionImport, FunctionImportMapping mapping)
364+
public void AddFunctionImportMapping(FunctionImportMapping mapping)
360365
{
361-
m_functionImportMappings.Add(functionImport, mapping);
366+
Check.NotNull(mapping, "mapping");
367+
368+
m_functionImportMappings.Add(mapping.FunctionImport, mapping);
362369
}
363370

364371
internal virtual bool TryGetFunctionImportMapping(EdmFunction functionImport, out FunctionImportMapping mapping)

src/EntityFramework/Core/Mapping/StorageMappingItemLoader.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1758,7 +1758,7 @@ private void LoadFunctionImportMapping(XPathNavigator nav, StorageEntityContaine
17581758
}
17591759
Debug.Assert(mapping != null, "mapping != null");
17601760

1761-
entityContainerMapping.AddFunctionImportMapping(functionImport, mapping);
1761+
entityContainerMapping.AddFunctionImportMapping(mapping);
17621762
}
17631763
else
17641764
{
@@ -1791,7 +1791,7 @@ private void LoadFunctionImportMapping(XPathNavigator nav, StorageEntityContaine
17911791
}
17921792
}
17931793

1794-
entityContainerMapping.AddFunctionImportMapping(functionImport, mapping);
1794+
entityContainerMapping.AddFunctionImportMapping(mapping);
17951795
}
17961796
}
17971797

src/EntityFramework/Core/Mapping/StorageScalarPropertyMapping.cs

+10-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace System.Data.Entity.Core.Mapping
44
{
55
using System.Data.Entity.Core.Metadata.Edm;
6+
using System.Data.Entity.Resources;
67
using System.Data.Entity.Utilities;
78
using System.Diagnostics;
89

@@ -45,15 +46,17 @@ public class StorageScalarPropertyMapping : StoragePropertyMapping
4546
/// </summary>
4647
/// <param name="member"> </param>
4748
/// <param name="columnMember"> </param>
48-
internal StorageScalarPropertyMapping(EdmProperty member, EdmProperty columnMember)
49+
public StorageScalarPropertyMapping(EdmProperty member, EdmProperty columnMember)
4950
: base(member)
5051
{
51-
DebugCheck.NotNull(columnMember);
52-
Debug.Assert(
53-
Helper.IsScalarType(member.TypeUsage.EdmType),
54-
"StorageScalarPropertyMapping must only map primitive or enum types");
55-
Debug.Assert(
56-
Helper.IsPrimitiveType(columnMember.TypeUsage.EdmType), "StorageScalarPropertyMapping must only map primitive types");
52+
Check.NotNull(member, "member");
53+
Check.NotNull(columnMember, "columnMember");
54+
55+
if (!Helper.IsScalarType(member.TypeUsage.EdmType)
56+
|| !Helper.IsPrimitiveType(columnMember.TypeUsage.EdmType))
57+
{
58+
throw new ArgumentException(Strings.StorageScalarPropertyMapping_OnlyScalarPropertiesAllowed);
59+
}
5760

5861
m_columnMember = columnMember;
5962
}

src/EntityFramework/Properties/Resources.cs

+47
Original file line numberDiff line numberDiff line change
@@ -12245,6 +12245,38 @@ internal static string ComposableFunctionOrFunctionImportMustDeclareReturnType
1224512245
get { return EntityRes.GetString(EntityRes.ComposableFunctionOrFunctionImportMustDeclareReturnType); }
1224612246
}
1224712247

12248+
/// <summary>
12249+
/// A string like "Argument '{0}' is invalid. The specified function is not marked as composable."
12250+
/// </summary>
12251+
internal static string NonComposableFunctionCannotBeMappedAsComposable(object p0)
12252+
{
12253+
return EntityRes.GetString(EntityRes.NonComposableFunctionCannotBeMappedAsComposable, p0);
12254+
}
12255+
12256+
/// <summary>
12257+
/// A string like "Mapping function imports returning entities is not supported."
12258+
/// </summary>
12259+
internal static string ComposableFunctionImportsReturningEntitiesNotSupported
12260+
{
12261+
get { return EntityRes.GetString(EntityRes.ComposableFunctionImportsReturningEntitiesNotSupported); }
12262+
}
12263+
12264+
/// <summary>
12265+
/// A string like "Structural type mappings must not be null or empty for function imports returning non-scalar values."
12266+
/// </summary>
12267+
internal static string StructuralTypeMappingsMustNotBeNullForFunctionImportsReturingNonScalarValues
12268+
{
12269+
get { return EntityRes.GetString(EntityRes.StructuralTypeMappingsMustNotBeNullForFunctionImportsReturingNonScalarValues); }
12270+
}
12271+
12272+
/// <summary>
12273+
/// A string like "Invalid return type for composable function."
12274+
/// </summary>
12275+
internal static string InvalidReturnTypeForComposableFunction
12276+
{
12277+
get { return EntityRes.GetString(EntityRes.InvalidReturnTypeForComposableFunction); }
12278+
}
12279+
1224812280
/// <summary>
1224912281
/// A string like "Functions that cannot be composed must not declare a return type."
1225012282
/// </summary>
@@ -13380,12 +13412,22 @@ internal static string VisitDbInExpressionNotImplemented
1338013412
{
1338113413
get { return EntityRes.GetString(EntityRes.VisitDbInExpressionNotImplemented); }
1338213414
}
13415+
13416+
/// <summary>
1338313417
/// A string like "Argument '{0}' is not valid. The specified mapping already exists or property paths are empty."
1338413418
/// </summary>
1338513419
internal static string InvalidColumnBuilderArgument(object p0)
1338613420
{
1338713421
return EntityRes.GetString(EntityRes.InvalidColumnBuilderArgument, p0);
1338813422
}
13423+
13424+
/// <summary>
13425+
/// A string like "Invalid scalar property mapping. Both entity model property and store column must be scalar properties."
13426+
/// </summary>
13427+
internal static string StorageScalarPropertyMapping_OnlyScalarPropertiesAllowed
13428+
{
13429+
get { return EntityRes.GetString(EntityRes.StorageScalarPropertyMapping_OnlyScalarPropertiesAllowed); }
13430+
}
1338913431
}
1339013432

1339113433
/// <summary>
@@ -16612,6 +16654,10 @@ internal sealed class EntityRes
1661216654
internal const string EndWithoutMultiplicity = "EndWithoutMultiplicity";
1661316655
internal const string EntityContainerCannotExtendItself = "EntityContainerCannotExtendItself";
1661416656
internal const string ComposableFunctionOrFunctionImportMustDeclareReturnType = "ComposableFunctionOrFunctionImportMustDeclareReturnType";
16657+
internal const string NonComposableFunctionCannotBeMappedAsComposable = "NonComposableFunctionCannotBeMappedAsComposable";
16658+
internal const string ComposableFunctionImportsReturningEntitiesNotSupported = "ComposableFunctionImportsReturningEntitiesNotSupported";
16659+
internal const string StructuralTypeMappingsMustNotBeNullForFunctionImportsReturingNonScalarValues = "StructuralTypeMappingsMustNotBeNullForFunctionImportsReturingNonScalarValues";
16660+
internal const string InvalidReturnTypeForComposableFunction = "InvalidReturnTypeForComposableFunction";
1661516661
internal const string NonComposableFunctionMustNotDeclareReturnType = "NonComposableFunctionMustNotDeclareReturnType";
1661616662
internal const string CommandTextFunctionsNotComposable = "CommandTextFunctionsNotComposable";
1661716663
internal const string CommandTextFunctionsCannotDeclareStoreFunctionName = "CommandTextFunctionsCannotDeclareStoreFunctionName";
@@ -16755,6 +16801,7 @@ internal sealed class EntityRes
1675516801
internal const string AssociationSet_EndEntityTypeMismatch = "AssociationSet_EndEntityTypeMismatch";
1675616802
internal const string VisitDbInExpressionNotImplemented = "VisitDbInExpressionNotImplemented";
1675716803
internal const string InvalidColumnBuilderArgument = "InvalidColumnBuilderArgument";
16804+
internal const string StorageScalarPropertyMapping_OnlyScalarPropertiesAllowed = "StorageScalarPropertyMapping_OnlyScalarPropertiesAllowed";
1675816805

1675916806
private static EntityRes loader;
1676016807
private readonly ResourceManager resources;

src/EntityFramework/Properties/Resources.resx

+16-1
Original file line numberDiff line numberDiff line change
@@ -4882,6 +4882,18 @@
48824882
<data name="ComposableFunctionOrFunctionImportMustDeclareReturnType" xml:space="preserve">
48834883
<value>Functions and function imports that can be composed must declare a return type.</value>
48844884
</data>
4885+
<data name="NonComposableFunctionCannotBeMappedAsComposable">
4886+
<value>Argument '{0}' is invalid. The specified function is not marked as composable.</value>
4887+
</data>
4888+
<data name="ComposableFunctionImportsReturningEntitiesNotSupported">
4889+
<value>Mapping function imports returning entities is not supported.</value>
4890+
</data>
4891+
<data name="StructuralTypeMappingsMustNotBeNullForFunctionImportsReturingNonScalarValues">
4892+
<value>Structural type mappings must not be null or empty for function imports returning non-scalar values.</value>
4893+
</data>
4894+
<data name="InvalidReturnTypeForComposableFunction">
4895+
<value>Invalid return type for composable function.</value>
4896+
</data>
48854897
<data name="NonComposableFunctionMustNotDeclareReturnType" xml:space="preserve">
48864898
<value>Functions that cannot be composed must not declare a return type.</value>
48874899
</data>
@@ -5325,7 +5337,7 @@
53255337
<data name="DbProviderNameAttributeNotFound" xml:space="preserve">
53265338
<value>The type '{0}' doesn't have DbProviderNameAttribute, please use an overload that has a provider invariant name string parameter.</value>
53275339
</data>
5328-
<data name="EdmProperty_InvalidPropertyType">
5340+
<data name="EdmProperty_InvalidPropertyType" xml:space="preserve">
53295341
<value>A property cannot be of type '{0}'. The property type must be a ComplexType, a PrimitiveType or an EnumType.</value>
53305342
</data>
53315343
<data name="ConcurrentMethodInvocation" xml:space="preserve">
@@ -5340,4 +5352,7 @@
53405352
<data name="InvalidColumnBuilderArgument" xml:space="preserve">
53415353
<value>Argument '{0}' is not valid. The specified mapping already exists or property paths are empty.</value>
53425354
</data>
5355+
<data name="StorageScalarPropertyMapping_OnlyScalarPropertiesAllowed" xml:space="preserve">
5356+
<value>Invalid scalar property mapping. Both entity model property and store column must be scalar properties.</value>
5357+
</data>
53435358
</root>

0 commit comments

Comments
 (0)