score:7

Accepted answer

Even if your query returns a single object, the Select method, which you are using behind the scenes, doesn't. It returns an IQueryable<T> in EF.

You should use a method such as Single, SingleOrDefault, First, FirstOrDefault if you want to store a single object.

var querySlotOrder = (from slot in context.CmsSlots
                      where slot.SlotId == myCurrentSlotId
                      select slot).Single();

The difference between the four methods is:

  • Single: Returns the only element of a sequence, and throws an exception if there is not exactly one element in the sequence.
  • SingleOrDefault: Returns the only element of a sequence, or a default value if the sequence is empty; this method throws an exception if there is more than one element in the sequence.
  • First: Returns the first element of a sequence.
  • FirstOrDefault: Returns the first element of a sequence, or a default value if the sequence contains no elements.

(Definitions from MSDN)

score:5

The LINQ select-statement always returns a queryable collection. Therefore you need to fetch a single object from it.

var querySlotOrder = (from slot in context.CmsSlots
                      where slot.SlotId == myCurrentSlotId
                      select slot).FirstOrDefault();

score:5

The type of the returned object is IQueryable<CmdSlot> (assuming that CmdSlot is the type of the elements), and querySlotOrder gets that type (that's the effect of var; var itself is not a type). If you are absolutely sure that there will always be exactly one element in the result collection, you can retrieve it with querySlotOrder.Single().

score:-3

Why do you use a var? if you know the type of the object you expect you should type querySlotOrder:

MyObjectType querySlotOrder = (from slot in context.CmsSlots
                             where slot.SlotId == myCurrentSlotId
                             select slot).FirstOrDefault();

           if (querySlotOrder.SlotOrder == myNewSlotOrder)
                e.Cancel = true;

score:2

As Dennis is pointing out in his answer, you're not getting an instance of one object, you're getting an IEnumerable back from your query. In order to access the SlotOrder property you need to pick a particular item from the collection, most likely the first - judging by your query.

score:3

The linq query returns not a record, but a collection of records that has only 1 element. If you want to get the first element and if you are sure that there is only 1 element in the collection, use Single extension method:

var querySlotOrders = from slot in context.CmsSlots
                      where slot.SlotId == myCurrentSlotId
                      select slot;
var querySlotOrder = querySlotOrders.Single();

if (querySlotOrder.SlotOrder == myNewSlotOrder)
    e.Cancel = true;

score:0

This is madd0's code but reformated to use C# style instead of SQL style

var querySlotOrder = context.CmsSlots
  .Where(slot => slot.SlotId == myCurrentSlotId)
  .Single();

it's better to read and understand whan SQL style


Related Articles