0

Following line throw exception if there is no matching record found.

Guid stuId= context.Students.FirstOrDefault(x => x.Name == student.Name).Id;

I understand, i can handle above line

var stuId= context.Students.FirstOrDefault(x => x.Name == student.Name);
if (stuId){}else{}

But,

Can i make the same line more smarter to handle no sequence found error

Guid stuId= context.Students.FirstOrDefault(x => x.Name == student.Name).Id;
Ian
  • 33,605
  • 26
  • 118
  • 198
simbada
  • 940
  • 4
  • 24
  • 43

4 Answers4

3

I think you should be able to use the new Null Conditional Operater like so:

Guid? stuId= context.Students.FirstOrDefault(x => x.Name == student.Name)?.Id;

You can read about this new syntax in C#6 on MSDN. Basically in addition the additional question mark, it will check that the statement before isn't null before executing the right hand side. If it is it'll return a null value so you need to make your Guid nullable.

Ian
  • 33,605
  • 26
  • 118
  • 198
  • 4
    Variable type should be `Guid?`. – kiziu Oct 13 '16 at 10:28
  • 1
    It must be `Guid?`, instead of simple `Guid`. – Yurii N. Oct 13 '16 at 10:28
  • And of course, the assumption is that you use C# 6. – kiziu Oct 13 '16 at 10:29
  • Correct, assuming C# 6 is available to the user, and then also `Guid?` must be used. – Peter B Oct 13 '16 at 10:29
  • I am using dot net 4.5 means C# 5. so your solution wont work with me – simbada Oct 13 '16 at 10:31
  • @simbada, version of framework is not the same as version of C#. – kiziu Oct 13 '16 at 10:31
  • Ok, but c# version is linked with dot net version. http://stackoverflow.com/questions/19532942/which-version-of-c-sharp-am-i-using – simbada Oct 13 '16 at 10:32
  • @simbada what kiziu said is true - it depends on your IDE. The code will compile down to .NET 4.5 regardless, it's ultimately just syntax sugar being applied by your IDE. – Ian Oct 13 '16 at 10:32
  • @simbada - The C# version is that of the written language. The .NET version is the version of the compiled runtime that you'll be executing. You can change the "Target" of a project normally to numerous runtime versions. – Ian Oct 13 '16 at 10:34
  • Alright, I am using VS2013. and it does not allow me to put ? after FirstOrDefault(x => x.Name == student.Name). Means i dont have c# 6? sorry but getting confuse now. – simbada Oct 13 '16 at 10:36
  • 1
    @simbada Yeah, that means you don't have it by default. But checkout http://stackoverflow.com/questions/27093908/how-to-enable-c-sharp-6-0-feature-in-visual-studio-2013 and you can be using the latest language features too :D – Ian Oct 13 '16 at 10:37
  • AFAIR you won't get the IDE's help with new features of greater version of C#, though it will still compile. – kiziu Oct 13 '16 at 10:41
2

Yes, with the null-propagation/conditional operator(new in C#6):

Guid? stuId = context.Students.FirstOrDefault(x => x.Name == student.Name)?.Id;

Now you have a nullable and it's easy to check if there is an id or not:

if(stuId.HasValue)
{
    // ...
}

If you can't use C#6 as commented:

Guid stuId = context.Students
    .Where(x => x.Name == student.Name)
    .Select(x=> x.Id)
    .DefaultIfEmpty(Guid.Empty)
    .First();

Now you can check against Guid.Empty:

if(stuId != Guid.Empty)
{

}

If Guid.Empty is a valid value you could also use a Guid? here:

Guid? stuId = context.Students
    .Where(x => x.Name == student.Name)
    .Select(x=> (Guid?) x.Id)
    .DefaultIfEmpty(null)
    .First();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • I am using dot net 4.5 means c# 5 so your solution wont work for me. – simbada Oct 13 '16 at 10:31
  • 1
    @simbada: added an alternative approach if you can't use C#6 – Tim Schmelter Oct 13 '16 at 10:35
  • I am checking that. Your 1st alternative solution returns empty GUID which probably not ok for me. All i want it should return null until unless i can't achieve it i am ok with your 1st alternative sol. – simbada Oct 13 '16 at 10:41
  • Checking your Alternative sol 2 now. – simbada Oct 13 '16 at 10:41
  • I'm getting `NotSupportedException` for `DefaultIfEmpty`. If you replace `DefaultIfEmpty(null).First()` with `FirstOrDefault()` as I described, it works fine. – kiziu Oct 13 '16 at 10:43
  • @Thanks Tim, your alternative solution 2 looks fine to me. – simbada Oct 13 '16 at 10:51
  • Correction/clarification: `DefaultIfEmpty` will not work with Linq2Sql, but most likely works with EF. – kiziu Oct 13 '16 at 10:56
  • @kiziu: if it doesn't work he can use `AsEnumerable()` between the `Select` and `DefaultIfEmpty(null)`. – Tim Schmelter Oct 13 '16 at 10:57
  • Sure, just seems like more unnecessary lines/fragments of code which can be solved easily by using `FirstOrDefault()`. – kiziu Oct 13 '16 at 10:59
  • @kiziu: maybe the actual query is bigger and he needs to integrate it into it or he needs to be able to change the returned vaue easier, then this approach comes in handy. But of course, the `!= null` check is easy and short. OP had just asked for a smarter one-statement approach. – Tim Schmelter Oct 13 '16 at 11:07
0

You could do it like this:

Guid? stuId = context.Students.FirstOrDefault(x => x.Name == student.Name)?.Id;
if ( stuId.HasValue )
{
    // do something if we have a value
}

Which is using the null conditional operator, but you still need to check if you actually got a value before trying to use the value

Thomas Schmidt
  • 359
  • 2
  • 11
0

If you want a solution working in lower version of C# than 6 (not using null-conditional operator), you can use cast operator like this:

var stuId = context.Students.Where(x => x.Name == student.Name).Select(i => (Guid?)i.Id).FirstOrDefault();

This will correctly return null if no record is found, as null is a default value for nullable structs.

kiziu
  • 1,111
  • 1
  • 11
  • 15
  • You should make your declaration `Guid?` on the left instead of `var`. It's non-obvious unless you understand all the expressions on the right. – Ian Oct 13 '16 at 10:37
  • Indeed, but I always use `var` unless I want a variable to be of more base type, like interface it implements. You can always use the IDE and just hover over the variable to see the type. – kiziu Oct 13 '16 at 10:38