BlueshiftSoftware / EntityFrameworkCore

NoSQL providers for EntityFramework Core
Other
281 stars 57 forks source link

Self refrence read not support #30

Closed SarcoZ closed 5 years ago

SarcoZ commented 5 years ago

public class Area { ///

/// Id /// [BsonId] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public ObjectId Id { get; private set; }

    public string Name { get; set; }

    public string Code { get; set; }

    public virtual Area Parent { get; set; }

    //[ForeignKey("Id")]

    public virtual ICollection<Area> Areas { get; set; }
}

Save success ,but can not read from mongo

crhairr commented 5 years ago

When reading a collection of entities, you either need to use .Include(area => area.Areas) or execute a group join. There are unit tests for both scenarios:

Including a collection: https://github.com/BlueshiftSoftware/EntityFrameworkCore/blob/f48e9b6b66e2575b89b5782418b1bc2d038e4002/test/Blueshift.EntityFrameworkCore.MongoDB.Tests/MongoDbContextTests.cs#L266

Using a group join: https://github.com/BlueshiftSoftware/EntityFrameworkCore/blob/f48e9b6b66e2575b89b5782418b1bc2d038e4002/test/Blueshift.EntityFrameworkCore.MongoDB.Tests/MongoDbContextTests.cs#L378

I treat any object with its own BsonId (or Key) property as a top-level entity, and I do not serialize them as part of the document. Instead, I serialize the necessary information to create a join to read the child element (e.g.: the id of the child object if that object doesn't contain a reference back to the parent). This saves space in the persisted document and allows for a much more flexible use of the collection.

SarcoZ commented 5 years ago

@crhairr when use var m = await Context.Set().Where(p => p.Name == "XX")
.Include(p => p.Parent) .Include(p => p.Areas) .ToListAsync();

Still error,can make a sample in test unit? fail: System.Linq.Expressions[3721] 异常信息 System.ArgumentException: Property 'MongoDB.Bson.ObjectId Id' is not defined for type 'System.Collections.Generic.ICollection1[Fengpin.Dcp.Entity.BusinessEntity.Area]' Parameter name: property at System.Linq.Expressions.Expression.Property(Expression expression, PropertyInfo property) at System.Linq.Expressions.Expression.MakeMemberAccess(Expression expression, MemberInfo member) at Blueshift.EntityFrameworkCore.MongoDB.Query.ExpressionVisitors.MongoDbMemberAccessBindingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression) at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor) at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node) at Blueshift.EntityFrameworkCore.MongoDB.Query.MongoDbEntityQueryModelVisitor.ReplaceClauseReferences(Expression expression, IQuerySource querySource, Boolean inProjection) at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitGroupJoinClause(GroupJoinClause groupJoinClause, QueryModel queryModel, Int32 index) at Remotion.Linq.Clauses.GroupJoinClause.Accept(IQueryModelVisitor visitor, QueryModel queryModel, Int32 index) at Remotion.Linq.QueryModelVisitorBase.VisitBodyClauses(ObservableCollection1 bodyClauses, QueryModel queryModel) at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.VisitQueryModel(QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateAsyncQueryExecutor[TResult](QueryModel queryModel) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass22_01.<CompileAsyncQuery>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddAsyncQuery[TResult](Object cacheKey, Func1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileAsyncQuery[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.System.Collections.Generic.IAsyncEnumerable.GetEnumerator() at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.IncludableQueryable2.System.Collections.Generic.IAsyncEnumerable<TEntity>.GetEnumerator() at System.Linq.AsyncEnumerable.Aggregate_[TSource,TAccumulate,TResult](IAsyncEnumerable1 source, TAccumulate seed, Func3 accumulator, Func2 resultSelector, CancellationToken cancellationToken) at Fengpin.Dcp.ApiService.Controllers.AreaController.AreaInsert(Area area) in D:\个人\风聘\datacenter\Fengpin.Dcp.ApiService\Controllers\AreaController.cs:line 45 at lambda_method(Closure , Object ) at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult() at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at System.Threading.Tasks.ValueTask`1.get_Result() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync() at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync() at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()

SarcoZ commented 5 years ago

@crhairr I try many times, self loop refrence read still error