Description
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
|