Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I think you've actually found a bug in Entity Framework. I'm envious!</p> <p><strong>(EDIT: It looks like this bug has been fixed in EF 6.0.0-rc1)</strong></p> <p>Here's why I think it's a bug: the machinery which is translating the expression predicate is definitely misbehaving for <code>FirstOrDefault</code> in a way that does not occur with <code>Where</code>. I can repro your issue against a similar schema with these contrived queries:</p> <pre><code>// works var target = _context.Orders.Where (o =&gt; _context.Users.FirstOrDefault() != null).FirstOrDefault (); // Exception: Unable to create a constant value... target = _context.Orders.FirstOrDefault (o =&gt; _context.Users.FirstOrDefault() != null); </code></pre> <p>Not only does it throw an exception, but observing the SQL in LINQPad you can see that an effective <code>SELECT * FROM Users</code> query is being issued right before it blows up, as if it's trying to treat the <code>_context.Users.FirstOrDefault()</code> call as the <code>IEnumerable</code> version rather than the <code>IQueryable</code> version. Using an unmapped method as a predicate in the inner <code>FirstOrDefault</code> call results in the same "constant value" exception, rather than the "LINQ to Entities does not recognize the method" exception one would expect:</p> <pre><code>// throws "Unable to create a constant value..." exception! target = _context.Orders.FirstOrDefault (o =&gt; _context.Users.FirstOrDefault(u =&gt; MyBogusMethod(u)) != null); </code></pre> <p>It's as if the translator for <code>FirstOrDefault</code> is aggressively trying to reduce an expression of type <code>User</code> down to an instance of type <code>User</code> by executing the expression somehow, but before the reduction is complete (before the inner <code>FirstOrDefault</code> is evaluated) it realizes that the resulting type is not going to be allowed and blows up. Very strange.</p> <p>I briefly tried to figure out what's going wrong in the source, but it's way beyond me. <del>I'd recommend filing a bug with the EF guys: <a href="http://entityframework.codeplex.com/workitem/list/basic" rel="nofollow">http://entityframework.codeplex.com/workitem/list/basic</a></del></p> <p>In the meantime, it seems to work correctly as long as you put the predicate in the <code>Where</code> clause rather than the <code>FirstOrDefault</code>, even if you tag <code>FirstOrDefault</code> onto the end of your query:</p> <pre><code>var target = _context.Orders.Where(o =&gt; o.OrderID == order.OrderID &amp;&amp; (o.User.UserName.ToLower() == userName || _context.Users.FirstOrDefault(u =&gt; u.UserName == userName).Role.RoleName == "Administrator") ) .FirstOrDefault(); </code></pre> <p>(You might also consider storing the fact that the user has the "Administrator" role on the <code>User</code>, to avoid the need for complex queries like this.)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload