Skip to content

Commit

Permalink
Finishing touches
Browse files Browse the repository at this point in the history
  • Loading branch information
AndriySvyryd committed Aug 4, 2022
1 parent 23345b2 commit 0821b27
Show file tree
Hide file tree
Showing 17 changed files with 198 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.



// ReSharper disable once CheckNamespace
namespace Microsoft.EntityFrameworkCore.Metadata.Conventions;

Expand Down
5 changes: 5 additions & 0 deletions src/EFCore.Relational/Metadata/IColumnBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public interface IColumnBase : IAnnotatable
/// </summary>
Type ProviderClrType { get; }

/// <summary>
/// Gets the type mapping for the column-like object.
/// </summary>
RelationalTypeMapping StoreTypeMapping { get; }

/// <summary>
/// Gets the value indicating whether the column can contain NULL.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ public interface IMutableStoredProcedureParameter : IReadOnlyStoredProcedurePara
/// <summary>
/// Gets or sets the direction of the parameter.
/// </summary>
new static ParameterDirection Direction { get; set; }
new ParameterDirection Direction { get; set; }
}
11 changes: 10 additions & 1 deletion src/EFCore.Relational/Metadata/Internal/ColumnBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,21 @@ public virtual Type ProviderClrType
return _providerClrType;
}

var typeMapping = PropertyMappings.First().TypeMapping;
var typeMapping = StoreTypeMapping;
var providerType = typeMapping.Converter?.ProviderClrType ?? typeMapping.ClrType;

return _providerClrType = providerType;
}
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual RelationalTypeMapping StoreTypeMapping
=> PropertyMappings.First().TypeMapping;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
77 changes: 52 additions & 25 deletions src/EFCore.Relational/Metadata/Internal/RelationalModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ private static void AddStoredProcedures(

if (tableMapping != null)
{
tableMapping.InsertStoredProcedureMapping = deleteProcedureMapping;
tableMapping.DeleteStoredProcedureMapping = deleteProcedureMapping;
}
}
else if (entityType == mappedType)
Expand All @@ -976,7 +976,7 @@ private static void AddStoredProcedures(

if (tableMapping != null)
{
tableMapping.InsertStoredProcedureMapping = updateProcedureMapping;
tableMapping.UpdateStoredProcedureMapping = updateProcedureMapping;
}
}
else if (entityType == mappedType)
Expand Down Expand Up @@ -1038,7 +1038,7 @@ private static StoredProcedureMapping CreateStoredProcedureMapping(
RelationalAnnotationNames.UpdateStoredProcedureResultColumnMappings),
_ => throw new Exception("Unexpected stored procedure type: " + identifier.StoreObjectType)
};

var position = -1;
foreach (var parameter in storedProcedure.Parameters)
{
Expand All @@ -1055,7 +1055,7 @@ private static StoredProcedureMapping CreateStoredProcedureMapping(

continue;
}

var property = mappedType.FindProperty(parameter.PropertyName);
if (property == null)
{
Expand Down Expand Up @@ -1120,7 +1120,7 @@ private static StoredProcedureMapping CreateStoredProcedureMapping(

continue;
}

var property = mappedType.FindProperty(resultColumn.PropertyName);
if (property == null)
{
Expand Down Expand Up @@ -1189,10 +1189,12 @@ static StoreStoredProcedure GetOrCreateStoreStoredProcedure(
storeStoredProcedure = new StoreStoredProcedure(storedProcedure, model);
if (storedProcedure.AreRowsAffectedReturned)
{
var typeMapping = relationalTypeMappingSource.FindMapping(typeof(int))!;
storeStoredProcedure.Return = new StoreStoredProcedureReturn(
"",
relationalTypeMappingSource.FindMapping(typeof(int))!.StoreType,
storeStoredProcedure);
typeMapping.StoreType,
storeStoredProcedure,
typeMapping);
}
model.StoredProcedures.Add((storeStoredProcedure.Name, storeStoredProcedure.Schema), storeStoredProcedure);
}
Expand All @@ -1218,25 +1220,38 @@ static StoreStoredProcedureParameter GetOrCreateStoreStoredProcedureParameter(
var storeParameter = (StoreStoredProcedureParameter?)storeStoredProcedure.FindParameter(name);
if (storeParameter == null)
{
storeParameter = new StoreStoredProcedureParameter(
name,
property?.GetColumnType(identifier)
?? relationalTypeMappingSource.FindMapping(typeof(int))!.StoreType,
position,
storeStoredProcedure,
parameter.Direction)
if (property == null)
{
IsNullable = property?.IsColumnNullable(identifier) ?? false
};
var typeMapping = relationalTypeMappingSource.FindMapping(typeof(int))!;
storeParameter = new StoreStoredProcedureParameter(
name,
typeMapping.StoreType,
position,
storeStoredProcedure,
parameter.Direction,
typeMapping);
}
else
{
storeParameter = new StoreStoredProcedureParameter(
name,
property.GetColumnType(identifier),
position,
storeStoredProcedure,
parameter.Direction)
{
IsNullable = property.IsColumnNullable(identifier)
};
}

((IRuntimeStoredProcedureParameter)parameter).StoreParameter = storeParameter;
storeStoredProcedure.AddParameter(storeParameter);
}
else if (property?.IsColumnNullable(identifier) == false)
{
storeParameter.IsNullable = false;
}


((IRuntimeStoredProcedureParameter)parameter).StoreParameter = storeParameter;
return storeParameter;
}

Expand All @@ -1251,21 +1266,33 @@ static StoreStoredProcedureResultColumn GetOrCreateStoreStoredProcedureResultCol
var column = (StoreStoredProcedureResultColumn?)storeStoredProcedure.FindResultColumn(name);
if (column == null)
{
column = new StoreStoredProcedureResultColumn(
name,
property?.GetColumnType(identifier)
?? relationalTypeMappingSource.FindMapping(typeof(int))!.StoreType,
storeStoredProcedure)
if (property == null)
{
IsNullable = property?.IsColumnNullable(identifier) ?? false
};
var typeMapping = relationalTypeMappingSource.FindMapping(typeof(int))!;
column = new StoreStoredProcedureResultColumn(
name,
typeMapping.StoreType,
storeStoredProcedure);
}
else
{
column = new StoreStoredProcedureResultColumn(
name,
property.GetColumnType(identifier),
storeStoredProcedure)
{
IsNullable = property.IsColumnNullable(identifier)
};
}

storeStoredProcedure.AddResultColumn(column);
}
else if (property?.IsColumnNullable(identifier) == false)
{
column.IsNullable = false;
}

((IRuntimeStoredProcedureResultColumn)resultColumn).StoreResultColumn = column;
return column;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal;
public class StoreStoredProcedureParameter
: ColumnBase<StoredProcedureParameterMapping>, IStoreStoredProcedureParameter
{
private readonly RelationalTypeMapping? _storeTypeMapping;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand All @@ -25,11 +27,13 @@ public StoreStoredProcedureParameter(
string type,
int position,
StoreStoredProcedure storedProcedure,
ParameterDirection direction)
ParameterDirection direction,
RelationalTypeMapping? storeTypeMapping = null)
: base(name, type, storedProcedure)
{
Position = position;
Direction = direction;
_storeTypeMapping = storeTypeMapping;
}

/// <summary>
Expand All @@ -56,6 +60,15 @@ public virtual StoreStoredProcedure StoredProcedure
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual int Position { get; }

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override RelationalTypeMapping StoreTypeMapping
=> _storeTypeMapping ?? base.StoreTypeMapping;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal;
public class StoreStoredProcedureResultColumn
: ColumnBase<StoredProcedureResultColumnMapping>, IStoreStoredProcedureResultColumn
{
private readonly RelationalTypeMapping? _storeTypeMapping;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand All @@ -21,9 +23,11 @@ public class StoreStoredProcedureResultColumn
public StoreStoredProcedureResultColumn(
string name,
string type,
StoreStoredProcedure storedProcedure)
StoreStoredProcedure storedProcedure,
RelationalTypeMapping? storeTypeMapping = null)
: base(name, type, storedProcedure)
{
_storeTypeMapping = storeTypeMapping;
}

/// <summary>
Expand All @@ -34,6 +38,15 @@ public StoreStoredProcedureResultColumn(
/// </summary>
public virtual StoreStoredProcedure StoredProcedure
=> (StoreStoredProcedure)Table;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override RelationalTypeMapping StoreTypeMapping
=> _storeTypeMapping ?? base.StoreTypeMapping;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace Microsoft.EntityFrameworkCore.Metadata.Internal;
/// </summary>
public class StoreStoredProcedureReturn : ColumnBase<ColumnMappingBase>, IStoreStoredProcedureReturn
{
private readonly RelationalTypeMapping? _storeTypeMapping;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
Expand All @@ -20,9 +22,11 @@ public class StoreStoredProcedureReturn : ColumnBase<ColumnMappingBase>, IStoreS
public StoreStoredProcedureReturn(
string name,
string type,
StoreStoredProcedure storedProcedure)
StoreStoredProcedure storedProcedure,
RelationalTypeMapping? storeTypeMapping = null)
: base(name, type, storedProcedure)
{
_storeTypeMapping = storeTypeMapping;
}

/// <summary>
Expand All @@ -33,6 +37,15 @@ public StoreStoredProcedureReturn(
/// </summary>
public virtual StoreStoredProcedure StoredProcedure
=> (StoreStoredProcedure)Table;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public override RelationalTypeMapping StoreTypeMapping
=> _storeTypeMapping ?? base.StoreTypeMapping;

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,22 @@ public StoredProcedureParameterMapping(
: base(property, storeParameter, storedProcedureMapping)
{
Parameter = parameter;
}

/// <inheritdoc />
}

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IStoredProcedureParameter Parameter { get; }

/// <inheritdoc />
/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IStoredProcedureMapping StoredProcedureMapping
=> (IStoredProcedureMapping)TableMapping;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,19 @@ public StoredProcedureResultColumnMapping(
}

/// <summary>
/// Gets the associated stored procedure result column.
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IStoredProcedureResultColumn ResultColumn { get; }

/// <inheritdoc />

/// <summary>
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
/// any release. You should only use it directly in your code with extreme caution and knowing that
/// doing so can result in application failures when updating to a new Entity Framework Core release.
/// </summary>
public virtual IStoredProcedureMapping StoredProcedureMapping
=> (IStoredProcedureMapping)TableMapping;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1011,8 +1011,8 @@ protected virtual IEnumerable<MigrationOperation> Diff(
IsDestructiveChange = isDestructiveChange
};

var sourceTypeMapping = source.PropertyMappings.First().TypeMapping;
var targetTypeMapping = target.PropertyMappings.First().TypeMapping;
var sourceTypeMapping = source.StoreTypeMapping;
var targetTypeMapping = target.StoreTypeMapping;

Initialize(
alterColumnOperation, target, targetTypeMapping,
Expand Down Expand Up @@ -1059,8 +1059,7 @@ protected virtual IEnumerable<MigrationOperation> Add(
Name = target.Name
};

var targetMapping = target.PropertyMappings.First();
var targetTypeMapping = targetMapping.TypeMapping;
var targetTypeMapping = target.StoreTypeMapping;

Initialize(
operation, target, targetTypeMapping, target.IsNullable,
Expand Down
Loading

0 comments on commit 0821b27

Please sign in to comment.