无法将类型 A 转换为类型 B。LINQ to Entities 仅支持转换 EDM 原语或枚举类型
Unable to cast the type A to type B. LINQ to Entities only supports casting EDM primitive or enumeration types
我在我的项目中首先使用 EF 代码,我有以下实体:
public class WorkcenterCapacity : ITimePeriodEntity
{
public int Id { get; set; }
public decimal AvailableCapacity { get; set; }
public DateTime FromTime { get; set; }
public DateTime ToTime { get; set; }
}
public interface ITimePeriodEntity
{
DateTime FromTime { get; set; }
DateTime ToTime { get; set; }
}
我也用 PredicateBuilder 做了一个动态谓词。出于可用性目的,我定义了以下通用 class:
public static class CropPredicateBuilder<T> where T : ITimePeriodEntity
{
public static Expression<Func<T, bool>> Creat(DateTime windowStart,
DateTime windowFinish)
{
var result = PredicateBuilder.False<T>();
Expression<Func<T, bool>> completelyInWindowRanges =
x => x.FromTime >= windowStart && x.ToTime <= windowFinish;
Expression<Func<T, bool>> startIsInWindowRanges =
x => x.FromTime >= windowStart && x.FromTime <= windowFinish;
Expression<Func<T, bool>> finishIsInWindowRanges =
x => x.ToTime >= windowStart && x.ToTime <= windowFinish;
Expression<Func<T, bool>> overlapDateRangeWindow =
x => x.FromTime <= windowStart && x.ToTime >= windowFinish;
return result.Or(completelyInWindowRanges)
.Or(startIsInWindowRanges)
.Or(finishIsInWindowRanges)
.Or(overlapDateRangeWindow);
}
}
并按如下方式使用它:
var predicate = CropPredicateBuilder<WorkcenterCapacity>
.Creat(DateTime.Now,DateTime.Now.AddDays(10));
var workcenterCapacities = dbContext.WorkcenterCapacities
.AsNoTracking()
.Where(predicate)
.AsExpandable()
.ToList();
但是当我 运行 它时,我得到以下错误:
Unable to cast the type 'WorkcenterCapacity' to type 'ITimePeriodEntity'. LINQ to Entities
only supports casting EDM primitive or enumeration types.
我该如何解决这个问题?
这样试试
where T : class, ITimePeriodEntity
要第一个约束是class。我认为这是要确定的。
顺便说一句,这也可以解决问题,而且速度可能更快。
public static class CropPredicateBuilder<T> where T : class, ITimePeriodEntity
{
public static Expression<Func<T, bool>> Creat(DateTime windowStart,
DateTime windowFinish)
{
var result = PredicateBuilder.False<T>();
Expression<Func<T, bool>> startBeforeToTime =
x => windowStart <= x.ToTime;
Expression<Func<T, bool>> finishAfterFromTime =
x => windowFinish >= x.FromTime;
return result.Or(startBeforeToTime)
.Or(finishAfterFromTime);
}
}
我在我的项目中首先使用 EF 代码,我有以下实体:
public class WorkcenterCapacity : ITimePeriodEntity
{
public int Id { get; set; }
public decimal AvailableCapacity { get; set; }
public DateTime FromTime { get; set; }
public DateTime ToTime { get; set; }
}
public interface ITimePeriodEntity
{
DateTime FromTime { get; set; }
DateTime ToTime { get; set; }
}
我也用 PredicateBuilder 做了一个动态谓词。出于可用性目的,我定义了以下通用 class:
public static class CropPredicateBuilder<T> where T : ITimePeriodEntity
{
public static Expression<Func<T, bool>> Creat(DateTime windowStart,
DateTime windowFinish)
{
var result = PredicateBuilder.False<T>();
Expression<Func<T, bool>> completelyInWindowRanges =
x => x.FromTime >= windowStart && x.ToTime <= windowFinish;
Expression<Func<T, bool>> startIsInWindowRanges =
x => x.FromTime >= windowStart && x.FromTime <= windowFinish;
Expression<Func<T, bool>> finishIsInWindowRanges =
x => x.ToTime >= windowStart && x.ToTime <= windowFinish;
Expression<Func<T, bool>> overlapDateRangeWindow =
x => x.FromTime <= windowStart && x.ToTime >= windowFinish;
return result.Or(completelyInWindowRanges)
.Or(startIsInWindowRanges)
.Or(finishIsInWindowRanges)
.Or(overlapDateRangeWindow);
}
}
并按如下方式使用它:
var predicate = CropPredicateBuilder<WorkcenterCapacity>
.Creat(DateTime.Now,DateTime.Now.AddDays(10));
var workcenterCapacities = dbContext.WorkcenterCapacities
.AsNoTracking()
.Where(predicate)
.AsExpandable()
.ToList();
但是当我 运行 它时,我得到以下错误:
Unable to cast the type 'WorkcenterCapacity' to type 'ITimePeriodEntity'. LINQ to Entities only supports casting EDM primitive or enumeration types.
我该如何解决这个问题?
这样试试
where T : class, ITimePeriodEntity
要第一个约束是class。我认为这是要确定的。
顺便说一句,这也可以解决问题,而且速度可能更快。
public static class CropPredicateBuilder<T> where T : class, ITimePeriodEntity
{
public static Expression<Func<T, bool>> Creat(DateTime windowStart,
DateTime windowFinish)
{
var result = PredicateBuilder.False<T>();
Expression<Func<T, bool>> startBeforeToTime =
x => windowStart <= x.ToTime;
Expression<Func<T, bool>> finishAfterFromTime =
x => windowFinish >= x.FromTime;
return result.Or(startBeforeToTime)
.Or(finishAfterFromTime);
}
}