Why asking
I already found a way to fix it, but it duplicates the code in Equals method and moreover I would like to understand the behavior.
Issue
Querying DbContext list of objects and filtering using a where clause that uses the Equals method of the object doesn't return the proper SQL query.
So, here is my Equals method:
public override bool Equals(object obj)
{
    if (obj == null) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj is not MetaMovie other) return false;
    if (other.Id > 0 && Id > 0) return other.Id == Id;
    return other.MetaSource == MetaSource && other.ExternalId == ExternalId;
}
Using:
var existingMovie = await db.MetaMovies.Where(m => m.Equals(movie)).FirstOrDefaultAsync();
Generate a where using Id even if movie.Id == 0 and I was expecting having a query that would have used the alternate key (ExternalId + MetaSource). But no!
Patch that would prefer to skip
Instead, I created this method in the MetaMovie class:
public static System.Linq.Expressions.Expression<Func<MetaMovie, bool>> IsEqual(MetaMovie other)
{
    if (other.Id > 0) return m => other.Id == m.Id;
    return m => other.MetaSource == m.MetaSource && other.ExternalId == m.ExternalId;
}
And now it returns the proper query depending if movie.Id == 0 or not using:
var existingMovie = await db.MetaMovies.Where(MetaMovie.IsEqual(movie)).FirstOrDefaultAsync();
Could someone tell me what is difference? Or even better, how could I only have the Equals method having the same behavior?
 
     
     
    