Summary
The latest MongoDB.Driver for C# switched the default LINQ Provider from 2 to 3. After trying to upgrade and use version 3 the code that used to work in V2 fails in V3.
Server versions: 5.0.13 Windows and 5.0.10 Ubuntu
How to Reproduce
internal class Program5 { public class Preference { public Guid Id { get; set; } public PreferenceType Type { get; set; } } public enum PreferenceType { EmailAlerts, Another } public interface IEmailAlertsPreference { bool Enabled { get; set; } string Description { get; set; } } public class EmailAlertsPreference : Preference, IEmailAlertsPreference { public EmailAlertsPreference() { Type = PreferenceType.EmailAlerts; } public bool Enabled { get; set; } public string Description { get; set; } } internal static void Main2(string[] args) { foreach (var linqProvider in new [] { LinqProvider.V2, LinqProvider.V3 }) { var builder = new MongoUrlBuilder { DatabaseName = "Sample", Server = new MongoServerAddress("localhost", 27017) }; var mongoClientSettings = MongoClientSettings.FromUrl(builder.ToMongoUrl()); mongoClientSettings.LinqProvider = linqProvider; var mongoClient = new MongoClient(mongoClientSettings); var mongoDatabase = mongoClient.GetDatabase(builder.DatabaseName); var preferencesCollection = mongoDatabase.GetCollection<Preference>("Preferences"); preferencesCollection.DeleteMany(c => true); preferencesCollection.InsertOne(new EmailAlertsPreference { Id = Guid.NewGuid(), Enabled = true, Description = $"{linqProvider} - Description" }); var queryableWithoutProjection = preferencesCollection.AsQueryable() .Where(p => p.Type == PreferenceType.EmailAlerts && ((EmailAlertsPreference)p).Enabled); Console.WriteLine("*************************"); Console.WriteLine("Without custom projection"); Console.WriteLine("*************************"); foreach (var emailAlertsPreference in queryableWithoutProjection.ToList().Cast<EmailAlertsPreference>()) { Console.WriteLine(emailAlertsPreference.Enabled); Console.WriteLine(emailAlertsPreference.Description); } Console.WriteLine("*************************"); Console.WriteLine(); Console.WriteLine("*************************"); Console.WriteLine("With custom projection"); Console.WriteLine("*************************"); Expression<Func<Preference, EmailAlertsPreference>> projection = p => new EmailAlertsPreference { Enabled = ((EmailAlertsPreference)p).Enabled, Description = ((EmailAlertsPreference)p).Description }; foreach (var emailAlertsPreference in queryableWithoutProjection.Select(projection).ToList()) { Console.WriteLine(emailAlertsPreference.Enabled); Console.WriteLine(emailAlertsPreference.Description); } Console.WriteLine("*************************"); Console.WriteLine(); Console.WriteLine(); } } }
Execution output:
************************* Without custom projection ************************* True V2 - Description ************************************************** With custom projection ************************* True V2 - Description ************************* ************************* Without custom projection ************************* True V3 - Description ************************************************** With custom projection *************************Unhandled Exception: MongoDB.Driver.Linq.ExpressionNotSupportedException: Expression not supported: Convert(p) because conversion to Sample.Program5+EmailAlertsPreference is not supported. at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ConvertExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, UnaryExpression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MemberExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, MemberExpression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MemberInitExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, MemberInitExpression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.Translate(TranslationContext context, Expression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(TranslationContext context, LambdaExpression lambdaExpression, IBsonSerializer parameterSerializer, Boolean asRoot) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.SelectMethodToPipelineTranslator.Translate(TranslationContext context, MethodCallExpression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators.ExpressionToPipelineTranslator.Translate(TranslationContext context, Expression expression) at MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToExecutableQueryTranslators.ExpressionToExecutableQueryTranslator.Translate[TDocument,TOutput](MongoQueryProvider`1 provider, Expression expression) at MongoDB.Driver.Linq.Linq3Implementation.MongoQuery`2.Execute() at MongoDB.Driver.Linq.Linq3Implementation.MongoQuery`2.GetEnumerator() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Sample.Program5.Main2(String[] args) in D:\tfs2015\Shared\Packages\Panda.DataAccess\Sample\Program5.cs:line 90 at Sample.Program.Main(String[] args) in D:\tfs2015\Shared\Packages\Panda.DataAccess\Sample\Program.cs:line 21