-
Notifications
You must be signed in to change notification settings - Fork 453
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1695 from linq2db/dynamic_store_mapping_support
Dynamic store configuration improvements
- Loading branch information
Showing
16 changed files
with
1,342 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
Source/LinqToDB/Expressions/MappingExpressionsExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
using LinqToDB.Common; | ||
using System; | ||
using System.Linq.Expressions; | ||
using System.Reflection; | ||
|
||
namespace LinqToDB.Extensions | ||
{ | ||
static class MappingExpressionsExtensions | ||
{ | ||
public static TExpression GetExpressionFromExpressionMember<TExpression>(this Type type, string memberName) | ||
where TExpression : Expression | ||
{ | ||
var members = type.GetStaticMembersEx(memberName); | ||
|
||
if (members.Length == 0) | ||
throw new LinqToDBException($"Static member '{memberName}' for type '{type.Name}' not found"); | ||
|
||
if (members.Length > 1) | ||
throw new LinqToDBException($"Ambiguous members '{memberName}' for type '{type.Name}' has been found"); | ||
|
||
switch (members[0]) | ||
{ | ||
case PropertyInfo propInfo: | ||
{ | ||
if (propInfo.GetValue(null, null) is TExpression expression) | ||
return expression; | ||
|
||
throw new LinqToDBException($"Property '{memberName}' for type '{type.Name}' should return expression"); | ||
} | ||
case MethodInfo method: | ||
{ | ||
if (method.GetParameters().Length > 0) | ||
throw new LinqToDBException($"Method '{memberName}' for type '{type.Name}' should have no parameters"); | ||
|
||
if (method.Invoke(null, Array<object>.Empty) is TExpression expression) | ||
return expression; | ||
|
||
throw new LinqToDBException($"Method '{memberName}' for type '{type.Name}' should return expression"); | ||
} | ||
default: | ||
throw new LinqToDBException( | ||
$"Member '{memberName}' for type '{type.Name}' should be static property or method"); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
using System; | ||
using System.Linq.Expressions; | ||
|
||
namespace LinqToDB.Mapping | ||
{ | ||
/// <summary> | ||
/// Configure setter and getter methods for dynamic columns. | ||
/// </summary> | ||
/// <remarks> | ||
/// Expected signatures for getter and setter: | ||
/// <code> | ||
/// // should return true and value of property, if property value found in storage | ||
/// // should return false if property value not found in storage | ||
/// static object Getter(Entity object, string propertyName, object defaultValue); | ||
/// // or | ||
/// object this.Getter(string propertyName, object defaultValue); | ||
/// // where defaultValue is default value for property type for current MappingSchema | ||
/// | ||
/// static void Setter(Entity object, string propertyName, object value) | ||
/// or | ||
/// void this.Setter(string propertyName, object value) | ||
/// </code> | ||
/// </remarks> | ||
/// <seealso cref="Attribute" /> | ||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] | ||
public class DynamicColumnAccessorAttribute : Attribute, IConfigurationProvider | ||
{ | ||
/// <summary> | ||
/// Gets or sets mapping schema configuration name, for which this attribute should be taken into account. | ||
/// <see cref="ProviderName"/> for standard names. | ||
/// Attributes with <c>null</c> or empty string <see cref="Configuration"/> value applied to all configurations (if no attribute found for current configuration). | ||
/// </summary> | ||
public string Configuration { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets name of dynamic properties property setter method. | ||
/// </summary> | ||
public string SetterMethod { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets name of dynamic properties property getter method. | ||
/// </summary> | ||
public string GetterMethod { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets name of dynamic properties property setter expression method or property. Method or property | ||
/// must be static. | ||
/// </summary> | ||
public string SetterExpressionMethod { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets name of dynamic properties property getter expression method or property. Method or property | ||
/// must be static. | ||
/// </summary> | ||
public string GetterExpressionMethod { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets name of dynamic properties property set expression. | ||
/// </summary> | ||
public LambdaExpression SetterExpression { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets name of dynamic properties property get expression. | ||
/// </summary> | ||
public LambdaExpression GetterExpression { get; set; } | ||
|
||
protected internal void Validate() | ||
{ | ||
var setters = 0; | ||
var getters = 0; | ||
if (SetterMethod != null) setters++; | ||
if (SetterExpressionMethod != null) setters++; | ||
if (SetterExpression != null) setters++; | ||
if (GetterMethod != null) getters++; | ||
if (GetterExpressionMethod != null) getters++; | ||
if (GetterExpression != null) getters++; | ||
|
||
if (setters != 1 || getters != 1) | ||
throw new LinqToDBException($"{nameof(DynamicColumnAccessorAttribute)} should have exactly one setter and getter configured."); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.