我编写了一个扩展方法,以便更轻松地在 EF 8(.NET 8)中添加多列索引,如下所示:
public static IndexBuilder<TEntityType> HasIndexUnique<TEntityType>
(
this EntityTypeBuilder<TEntityType> builder,
string indexName,
IEnumerable<Expression<Func<TEntityType, object?>>> includeExpressions
) where TEntityType : class
{
if ((includeExpressions is null) || (!includeExpressions.Any()))
{
var currentMethod = MethodBase.GetCurrentMethod();
throw (new Exception($@"The method [{currentMethod?.DeclaringType?.FullName}.{currentMethod?.Name}] was called without any [{nameof(includeExpressions)}]."));
}
var propertyNames = includeExpressions
.Select
(
e =>
// Casting issue depending on what was sent in.
((MemberExpression) ((UnaryExpression) e.Body).Operand).Member.Name
)
.ToArray();
var indexBuilder = builder
.HasIndex
(
propertyNames,
$@"{indexName}"
)
.IsUnique(unique: true);
return (indexBuilder);
}
的内置重载EntityTypeBuilder<TEntityType>.HasIndex
是string
基于的(我认为它很笨重)。支持语法的重载Expression
仅允许一列。上述方法非常有效,使调用代码更易于阅读。
builder
.HasIndexUnique
(
"Index_IndexName_Unique",
e => e.ModelId,
e => e.ModelEntityPrincipleId,
e => e.ModelEntityDependentId,
e => e.ModelEntityBridgeId
);
在上面的例子中,传入的所有属性都是 类型Int64
。当我尝试发送String
属性时,表达式转换失败。
builder.HasIndexUnique("Index_IndexName_Unique", e => e.Name);
// Exception at this line:
((MemberExpression) ((UnaryExpression) e.Body).Operand).Member.Name
System.InvalidCastException: 'Unable to cast object of type 'System.Linq.Expressions.PropertyExpression' to type 'System.Linq.Expressions.UnaryExpression'.'
如何检测和处理不同类型的属性以便正确转换它们?我已经预料到以下几种数据类型,这应该足够了:
Int64, String, DateTime, Object, Byte []
我希望得到一个解决方案,但也想了解是什么使得表达式成为一元表达式、属性表达式或其他我尚未探索过的类型。
编辑:
public partial class ModelEntityRelationship:
IEntity<ModelEntityRelationship>
{
public virtual long Id { get; set; }
public virtual string Name { get; set; }
public virtual long ModelId { get; set; }
public virtual Model Model { get; set; }
public virtual long ModelEntityPrincipleId { get; set; }
public virtual ModelEntity ModelEntityPrinciple { get; set; } = new();
public virtual long ModelEntityDependentId { get; set; }
public virtual ModelEntity ModelEntityDependent { get; set; } = new();
public virtual long? ModelEntityBridgeId { get; set; }
public virtual ModelEntity? ModelEntityBridge { get; set; }
}
我添加了源实体类来澄清我的困惑来源。除了数据类型之外,所有属性声明都是相同的。那么为什么在分别发送和对象时表达式类型Unary
会Property
从Int64
变为String
?
我建议创建扩展方法来删除不需要的转换,通过转换为对象值类型来添加。
因此,对于您而言,您可以简单地转换为
MemberExpression