entity framework - Unable to cast object of type 'System.Linq.Expressions.FieldExpression' to type 'System.Linq.Expressions.ParameterExpression -
i using entity framework rc1-final
in asp.net5.
i have following table.
public class playercomment { [key] public int id { get; set; } public int? periodid { get; set; } [foreignkey("periodid")] public period period { get; set; } public int? playerid { get; set; } [foreignkey("playerid")] public player player { get; set; public datetime? commentdate { get; set; } public string comment { get; set; } }
playercomment
linked player
linked subgroup
linked group
i have following linq query
public async task<ienumerable<playercomment>> searchqueryable(int? groupid, int? subgroupid = null, int? playerid = null) { var table = (from pc in _db.playercomments join p in _db.players on pc.playerid equals p.id join sg in _db.subgroups on p.subgroupid equals sg.id (sg.groupid == groupid || groupid == null) && (p.subgroupid == subgroupid || subgroupid == null) && (p.id == playerid || playerid == null) select pc); return table.tolistasync(); }
this works correctly.
every comment falls in period in output need include period add .include("period")
so code looks this
public async task<ienumerable<playercomment>> searchqueryable(int? groupid, int? subgroupid = null, int? playerid = null) { var table = (from pc in _db.playercomments join p in _db.players on pc.playerid equals p.id join sg in _db.subgroups on p.subgroupid equals sg.id (sg.groupid == groupid || groupid == null) && (p.subgroupid == subgroupid || subgroupid == null) && (p.id == playerid || playerid == null) select pc).include(p => p.period); return table.tolistasync(); }
however throws runtime exception , gives me:
"unable cast object of type 'system.linq.expressions.fieldexpression' type 'system.linq.expressions.parameterexpression'."
i read on github there issue orderby
giving error i'm not using order by.
is there workaround can use fix this?
i seem have narrowed down answer provided @octavioccl.
changing code this:
var table = _db.playercomments.include(q => q.period) .include(sg => sg.player.subgroup); iqueryable<playercomment> tablefiltered; if (playerid != null) { tablefiltered = table.where(p => p.player.id == playerid) } else { if (subgroupid != null) { tablefiltered = table.where(p => p.player.subgroupid == subgroupid) } else { if (groupid != null) { tablefiltered = table.where(p => p.player.subgroup.groupid == groupid) } else { tablefiltered = table } } } return tablefiltered;
all combinations work, except when select groupid
, keep others null
. since subgroup
works can deduce issue when use include , use clause 3 levels deep.
you should try calling include
method in dbset
want load related entity:
var table = (from pc in _db.playercomments.include(p => p.period) //...
and think query simpler if use navigation properties instead explicit joins:
var table =await _db.playercomments.include(p => p.period) .include(p => p.player.subgroup.group) .where(pc=> ( pc.player.subgroup.group.groupid == groupid || groupid == null) && ( pc.player.subgroup.subgroupid == subgroupid || subgroupid == null) && ( pc.player.id == playerid || playerid == null)) .tolistasync();
update
try moving conditions check if parameters null
outside of query.
bool groupidisnull=groupid == null; bool subgroupidisnull=subgroupid == null; bool playeridisnull= playerid==null; var table =await _db.playercomments.include(p => p.period) .include(p => p.player.subgroup.group) .where(pc=> ( groupidisnull || pc.player.subgroup.group.groupid.value == groupid.value) && ( subgroupidisnull || pc.player.subgroup.subgroupid.value == subgroupid.value ) && ( playeridisnull || pc.player.id.value == playerid.value)) .tolistasync();
Comments
Post a Comment