머리말LINQ는 EDM 기본 또는 열거 타입 (독특한 새 게시물)
나는이 특정 오류에 관한 아마 20 질문을 계산 캐스팅 지원하지만 나는 그들 중 하나가 적용된다는 것을 찾지 못했습니다. 저는 문자 람다 구문보다는 프로그래밍 방식으로 표현식을 작성한다는 점에서 다른 것을하고 있습니다. 나는 이것이 다른 합병증을 발굴 할 수 있다고 생각합니다.
아래 코드는 내 헬퍼 중 일부와 내 UnitOfWork 클래스를 사용합니다. 간결함을 위해 여기서 모든 것을 끌지는 않겠지 만 요청시 추가 코드를 제공 할 것입니다.
나는 SelectMany
에 IQueryable
작업을 수행하려고
질문. 표현을 글자 그대로 쓰면 작동합니다. 그러나이 모든 것을 동적으로 구축 할 수 있어야하므로 리터럴 표현식 옵션이 없습니다.
의견을 보려면 아래 코드를 참조하십시오.
public static void SelectManyTest()
{
int id = 14690;
var p = Expression.Parameter(typeof(SystemEntitlement));
var projector = ExpressionHelpers.GetLambda<SystemAssociate, SystemAssociateModel>(x => new SystemAssociateModel
{
role = x.Role.Name,
id = x.Associate.Id,
order = x.Order
});
var memberPath = ExpressionHelpers.GetLambda<SystemEntitlement, ICollection<SystemAssociate>>(
x => x.System.Associates).Body.AsMemberExpression().ReplaceInstance(p);
//These two calls equate to this: x.System.Associates.AsQueryable().Select(projector)
var call_asQueryable = Expression.Call(ExpressionHelpers.GetMethodInfo(() => Queryable.AsQueryable<SystemAssociate>(null)), memberPath);
Expression call_select = Expression.Call(ExpressionHelpers.GetMethodInfo(
() => Queryable.Select(default(IQueryable<SystemAssociate>), default(Expression<Func<SystemAssociate, SystemAssociateModel>>))),
call_asQueryable, projector);
//I use this in an attempt to cast my `Select` into `IEnumerable` for `SelectMany`. This
//is most likely where the issue is occurring. It makes sense that only specific types of
//casts would be supported within an expression.
//call_select = Expression.Convert(call_select, typeof(IEnumerable<SystemAssociateModel>));
//I have to use the uncommented line since that's the only one suitable for `.SelectMany`.
//This is the reason for the cast above, to convert `Select`'s `IQueryable` into an
//`IEnumerable` for `SelectMany`. If I don't use the explicit cast, it will attempt an
//implicit cast and still fail.
//var selector = (Expression<Func<SystemEntitlement, IQueryable<SystemAssociateModel>>>)Expression.Lambda(call_select, masterp);
var selector = (Expression<Func<SystemEntitlement, IEnumerable<SystemAssociateModel>>>)Expression.Lambda(call_select, p);
//This works so long as I write the `.SelectMany` expression literally. I seems that the compiler is somehow
//able to handle the implicit cast from `ICollection` to `IEnumerable`.
var associates1 = UnitOfWork.UseWith(work => work.GetRepo<SystemEntitlement>().AsQueryable()
.Where(x => x.Id == id)
.SelectMany(x => x.System.Associates.AsQueryable().Select(projector))
.Where(x => x.order == 1)
.ToArray());
//This throws the error in question.
var associates2 = UnitOfWork.UseWith(work => work.GetRepo<SystemEntitlement>().AsQueryable()
.Where(pred)
.SelectMany(selector)
.Where(x => x.order == 1)
.ToArray());
}
평소와 같이 식으로, 이반 Stoev 승리. 그 람다 오버로드를 사용하여 트릭을했습니다. AsQueryable을 호출하지 않는 경우, 원래 Select를 호출했지만 ICollection 내비게이션 속성에서 Select를 호출 할 수 없다는 것을 알 수 있습니다. 따라서이 방법으로 IQueryable로 변환해야하는 이유는 무엇입니까? – oscilatingcretin