0

I'm using Entity framework and I have a Repository class that does all the data fetching with a dbContext object.

Currently there's a method called

public MovieDetails FindSingle(int? id)
{
    using (MovieContext dbContext = new MovieContext())
    {
        var newMovieDetails = dbContext.Movies.FirstOrDefault(x => x.MovieID == id);
        if (newMovieDetails == null)
        {
            throw new Exception();
        }
        var MappedDetails = new MovieDetails
        {
            MovieID = newMovieDetails.MovieID,
            MovieName = newMovieDetails.MovieName
        };
        return MappedDetails;
    }
}

Currently when the program finds a match in database, it gets converted to a Data Object Transfer-object When I try to search for a movie that does not exist in database, I get an error. Is there a way I could return a type that says that no such row exists in database? Or should I just return an empty object?

sander
  • 1,426
  • 4
  • 19
  • 46

2 Answers2

2

you could use the package: https://github.com/vkhorikov/CSharpFunctionalExtensions#make-nulls-explicit-with-the-maybe-type

And then you can set as return:

public Maybe<MovieDetails> FindSingle(int? id)

So where you call your function, you know it could be null. Which you have to check: if (customerOrNothing.HasNoValue)

hope it helps!

Roelant M
  • 1,581
  • 1
  • 13
  • 28
0

Using an exception for something like this is a bad idea.
Exceptions are for exceptional things, namely things you can't control in your code like network errors and I/O permission violations.
This kind of thing is what Eric Lippert would call a vexing exception:

Vexing exceptions are the result of unfortunate design decisions. Vexing exceptions are thrown in a completely non-exceptional circumstance, and therefore must be caught and handled all the time.

The classic example of a vexing exception is Int32.Parse, which throws if you give it a string that cannot be parsed as an integer. But the 99% use case for this method is transforming strings input by the user, which could be any old thing, and therefore it is in no way exceptional for the parse to fail. Worse, there is no way for the caller to determine ahead of time whether their argument is bad without implementing the entire method themselves, in which case they wouldn't need to be calling it in the first place.

This unfortunate design decision was so vexing that of course the frameworks team implemented TryParse shortly thereafter which does the right thing.

If MappedDetails is a reference type, you better return null if it's not found.
If it's a value type, change your method to return MovieDetails? and return null.

I would also recommend changing your method name from FindSingle to GetMovieDetails or something along these lines.
This way, when you look at the code 6 months from now and see something like this:

....
var details = GetMovieDetails(id);
....

You can instantly know what the method actually does, as apposed to

....
var details = FindSingle(id);
....

that basically tells you nothing.

Community
  • 1
  • 1
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • What's the difference between value type and reference type? – sander May 17 '18 at 06:41
  • The method is named FindSingle because of an Interface. – sander May 17 '18 at 06:43
  • [difference between value type and reference type](https://stackoverflow.com/questions/5057267/what-is-the-difference-between-a-reference-type-and-value-type-in-c) – Zohar Peled May 17 '18 at 06:45
  • There are ways around that, like explicit interface implementation and a properly named method that the exiplicit interface implementation executes... or simply change the interface. Otherwise, be careful with the code using this method: `MovieDetails? details = FindSingle(MovieId);` is also readable enough. – Zohar Peled May 17 '18 at 06:49