加入集合和列表会在C#Mongodb强类型驱动程序中引发NotSupportedException

时间:2019-05-11 02:29:17

标签: c# .net mongodb mongodb-query mongodb-.net-driver

我正在使用官方的C#MongoDb强类型驱动程序版本2.8.0与MongoDB进行交互。

当我尝试将Meals类型的mongodb集合与MealsRequest类型的列表一起加入时,出现此异常:-

System.NotSupportedException: The joined collection cannot have any qualifiers."

这是我的代码:-

public class Meal
{
    [BsonId]
    [BsonRepresentation(representation: BsonType.ObjectId)]
    public string Id { get; set; }

    public string RestaurantId { get; set; }

    public string Category { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }

    public int Calories { get; set; }

    public string Photo { get; set; }
}

public class MealRequest
{
    [BsonId]
    [BsonRepresentation(representation: BsonType.ObjectId)]
    public string Id { get; set; }

    [Required(ErrorMessage = "This field is required")]
    public string MealId { get; set; }

    [Required(ErrorMessage = "This field is required")]
    public int Count { get; set; }

    public decimal Price { get; set; }

    public decimal MealTotal { get; set; }

    public string Name { get; set; }
}

这是引发异常的代码:-

var mealsRequests = await repository.Meals.AsQueryable()
    .Join(inner: mealsRequests, outerKeySelector: m => m.Id, innerKeySelector: mr => mr.MealId,
    resultSelector: (m, mr) => new MealRequest()
    {
        Id = mr.Id,
        MealId = m.Id,
        Count = mr.Count,
        Price = m.Price,
        Name = m.Name,
    }).ToListAsync();//Exception happens at this line 

return mealsRequests;

这是堆栈跟踪:-

System.NotSupportedException: The joined collection cannot have any qualifiers.
at MongoDB.Driver.Linq.Processors.Pipeline.MethodCallBinders.JoinBinder.Bind(PipelineExpression pipeline, PipelineBindingContext bindingContext, MethodCallExpression node, IEnumerable`1 arguments)
at MongoDB.Driver.Linq.Processors.MethodInfoMethodCallBinder`1.Bind(PipelineExpression pipeline, TBindingContext bindingContext, MethodCallExpression node, IEnumerable`1 arguments)
at MongoDB.Driver.Linq.Processors.PipelineBinderBase`1.BindMethodCall(MethodCallExpression node)
at MongoDB.Driver.Linq.Processors.Pipeline.PipelineBinder.Bind(Expression node, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Prepare(Expression expression)
at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.Translate(Expression expression)
at MongoDB.Driver.Linq.MongoQueryProviderImpl`1.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at MongoDB.Driver.Linq.MongoQueryableImpl`2.ToCursorAsync(CancellationToken cancellationToken)
at MongoDB.Driver.IAsyncCursorSourceExtensions.ToListAsync[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)

此异常的原因是什么?以及如何解决?

1 个答案:

答案 0 :(得分:0)

使用MongoDB.Entities,它是官方驱动程序的轻量级包装,

关系和导航非常容易。即使下面的示例是同步代码,它也具有异步功能。

using System.Linq;
using MongoDB.Entities;

namespace StackOverflow
{
    public class Meal : Entity
    {
        public string Name { get; set; }
        public Many<MealRequest> Requests { get; set; }

        public Meal() => this.InitOneToMany(() => Requests);
    }

    public class MealRequest : Entity
    {
        public One<Meal> Meal { get; set; }
        public string Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            new DB("retaurant-test");

            var meal = new Meal { Name = "pollo e funghi pasta" };
            meal.Save();

            var mealRequest = new MealRequest
            {
                Name = "pasta meal",
                Meal = meal.ToReference()
            };
            mealRequest.Save();

            meal.Requests.Add(mealRequest);

            var chickenMushroomPastaMealRequests = DB.Collection<MealRequest>()
                                                     .Where(mr => mr.Meal.ID == meal.ID)
                                                     .ToList();

            var resMealRequests = meal.Requests.Collection().ToList();

            var resMeal = resMealRequests.First().Meal.ToEntity();
        }
    }
}

如果必须使用官方驱动程序完成,我将使用linq进行以下操作:

var mealrequests = (from m in repo.Meals.AsQueryable()
                    join mr in repo.MealRequests.AsQueryable() on m.ID equals mr.MealID into requests
                    from r in requests
                    select r).ToList();