-
Notifications
You must be signed in to change notification settings - Fork 57
NullReferenceException with OO models #9
Comments
I'm surprised that there aren't any async tests for the MongoDb provider itself. However, ToListAsync() appears throughout the Identity provider, whose default user model uses nested documents for claims and tokens. I'll take a look at this and at the very least add some tests for the async provider usage. Does the exception occur on the call to ToListAsync() itself, or on the call to View()? If you're trying to display |
Nope, it comes from the call itself... right after stepping over that line (ToListAsync). I attached the project, you can download it and run it |
After reviewing the problem, I think I see what's going on. There's a relationship between Car and Owner which I misinterpreted as an "owned" relationship (a subdocument versus a navigation). The first thing to note here is that MongoDb is not a relational database. After all, it's called "NoSQL" for a reason. That said, recent versions of MongoDB have added support for the $lookup operator as a form of server-side join, but it does not behave the way you might think if you think of it as a replacement for the "LEFT JOIN" operator in SQL. There are some quirks to $lookup that I haven't accounted for yet, and as such EFCore-MongoDB currently does not fully support this kind of navigation property. I thought that there were checks in the model validation to ensure that no such navigations exist, but it appears they've been disabled or removed. There's a good guide to MongoDB schema design that explains what kinds of schemas MongoDB is designed to handle, and how to avoid schemas it isn't. In your case, I'd recommend nesting a I'll work on clearing up the confusion within the provider so that it's more obvious that navigations aren't fully supported right now. Since I'm the only active developer on this project, it might take me a while before I can work out the kinks in the navigation to get them working correctly. I apologize for the inconvenience. For what it's worth, I committed some changes last night that should obviate the need to use Also for what it's worth, I highly recommend you use a "view model" that separates your DB entities from the information displayed in your web views. This mapping layer allows you to introduce business logic validation that is completely separate from DB schema validation, which will make your application considerably more flexible. It also prevents the accidental leaking of potentially sensitive information from your database into a user's browser, assuming there are fields that contain business data that a user should never see directly. |
Actually, the design & architecture of this project is just cumbersome, no separate BLL and DAL projects since it's just a demo project after all. As you said, the right way of designing that scenario is to store the owner id:
Well, at least I was actually trying the subdocument feature in mongo... but it also opened the navigational properties subject 😄 But, this does not change the fact that the subdocument feature causes an exception when loading the document. As you know in EntityFrameworkCore.SqlServer, this is how we load the related properties:
This appears to cause another exception:
This is the exception when not including the Owner:
I hope there will support for the navigational properties since it will give us the advantage of using the OO model designing. |
Please do not use
There are several units tests built around subdocuments and subdocument querying: that feature works as expected as far as I'm aware. That said, I will expand the test model to reflect the use of interfaces, abstract classes, and shared data types. |
I've tried to update to the new build using the nuget powershell... the package doesn't exist (t0050c6393):
EDIT
|
After updating to the latest package(t0050c6393), retrieving the subdocument (owner) works fine 👍 |
Woohoo! That's what I like to see. If you don't mind, I'd like to keep this issue open as I work through the Navigations implementation. That way, I can send you an update if/when I get it working. |
I apologize for how long it took, but after a lot of research and going back and forth working around some issues in EF Core, I finally got navigations working. There are a few caveats:
It at least works for now. I'm going to continue working on navigation properties until it correctly uses the $lookup operator for a server-side join, but for now you can start uses models that make proper use of relationships. |
I will update the demo project as soon as possible to see if the navigation works between the owner and the car. ============== In case you don't already know: (In the mssql provider, I was working on another project, and even if X points to a collection of Y and Y doesn't point to X... it will automatically add a column in Y pointing to X). Here are the models:
This will result in adding a column to the Documents table that reserves the UniversityId automatically . |
Yeah, EF Core uses shadow properties to map relationships, and the columns are derived from those. It was one of the things I had to work around to get the navigations to work for a document DB. Also, I didn't see this last night before I posted, but the build appears to be broken. I'll have to fix it before you can pull an update where relationships will actually work. KoreBuild changed the way they do things and I have to figure it out. Sorry for the second delay! |
The build is fixed and a package has been published. The new version is 2.1.0-preview1 (keeping with EF-Core's current version). At some point, I'm going to expand the unit tests and prepare a final (non-preview) release. |
Sorry for the late response... gonna update my repo asap :) |
Hi, I couldn't get the latest update from myget... I tried by downloading the update from nuget UI, console, and csproj file.
|
Since EFCore-MongoDB is still in preview, it's being built against the current EFCore preview build. To get those - and all current .NET Core previews - you'll need to add this to your NuGet.config file: <add key="AspNetCore" value="https://dotnet.myget.org/F/aspnetcore-ci-dev/api/v3/index.json" /> This will go away when I publish the initial release (which will likely be as 2.1.0 to keep with the current EFCore release). |
Sorry for being late... I just wasted lots of time trying to get the packages and figured out I need to install the .net core 2.02 sdk ! I updated my demo repo by commenting out the joining code and adding the relationship between the Car and the Owner. Here is what I found: The navigation works fine in the normal case 😉
If you replace this line:
with this:
Even thought I explicitly made adding the entity goes into the owner collection:
|
I'm a bit confused as to what you're trying to accomplish there. But I'd like to point out a few things:
public class EntityA
{
[Key]
public ObjectId Id {get;}
}
public class ComplexType1
{
// This class does not have a Key, so it's treated as a complex type and
// this "navigation" will not be detected.
public EntityA EntityAItem {get;}
}
public class EntityB
{
[Key]
public ObjectId Id {get;}
// WILL NOT detect the navigation from ComplexType1 to EntityA.
// All values in the list, and the EntityAItem within, will be serialized
// as subdocuments of EntityB.
public IList<ComplexType1> List {get;}
// This will be treated as a proper navigation. Only the EntityA.Id will be serialized,
// and a $lookup (.Include(entityB => entityB.EntityAItem)) will be required to retrieve
// the instance of EntityA.
public EntityA EntityAItem {get;}
} Please note: without support for complex types in the EFCore metadata system, this CAN NOT be easily worked around. Feel free to help me convince the EFCore team to get proper complex type support implemented. They have implemented something called "Owned" types, but these do not behave as true complex types and do not support deep nesting (only one level of hierarchy below the parent). You can find the complex type issue in their repo's issue list here. |
I just realized the business logic is totally broken in the demo! What I'm trying to do is a simple rent-a-car app where:
I'm using the normal userManager to add the users and I got a Users collection that can be referred in the same mongodb instance, is there something wrong with this approach? I'm gonna work on those and add proper relationships... even I realized I didn't have a collection of cars in the owner model 😄 |
Async queries, complex type subdocuments, and relationship navigations are all supported. |
Great job ! After half a year of intense dev... I realized that the main problem was the model design, since mongodb is meant for de-normalizing. Quoting from a good read:
Src: https://dev.to/kenwalger/schema-design-considerations-in-mongodb-47f Also, for the inheritance part Isn't it the time fire this awesome package into nuget 😉 |
Hi,
While I was trying to see if mongo can fit my future projects, I landed to this provider... great work guys!
This issue is with version:
2.0.0-preview-t004f07459
.net core 2.0 project template made with vs 2017
Well, the ToListAsync causes an exception when there is a nested object, as in here:
But listing works fine when I have such a model (no nested documents):
Controller action is ordinary:
The text was updated successfully, but these errors were encountered: