Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 object is not a valid navigation #3737

Merged
merged 1 commit into from
Nov 13, 2015
Merged

🐛 object is not a valid navigation #3737

merged 1 commit into from
Nov 13, 2015

Conversation

smitpatel
Copy link
Contributor

Fixes #3727
Blocked object being discovered as entity type. Entity type with clr type System.Object is invalid entity type (due to absence of key) which is verified in model validator. Since System.Object is base type for any clr type, we set this entity type as base type for all other entities. Therefore we need to block it from being discovered in first place.
Also modified exception message in order to give information on what is the base type.

@@ -861,6 +861,8 @@ private class EntityWithNoValidNavigations
{
public int Id { get; set; }

public object Object { get; set; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to make sure, would it make sense to have a test in which:

  1. A CLR entity type derives from a base type that different from System.Object but isn't a valid entity type
  2. There is a property of that base type somewhere in the model?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have test to verify

  1. Non-primitive types are discovered as entity type
  2. When base type is present as entity type in the model then base type will be set for derived types
  3. When invalid entity is present in model throw exception
    Above scenario is just combination of all of them and should not be necessary.
    Though I can add test if you want. 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to see this test too. I'm not understanding how this fix will make the test Diego suggested pass.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is important that we understand the behavior in this general case because System.Object should just be just an example of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General behavior is,
If user have 2 entity types in the model added explicitly/conventionally, and if they are in CLR hierarchy then we will create TPH. We will throw exception if user tries to create key in derived type.
We will throw exception if there is any invalid entity type (entity without PK) regardless of above.

System.Object is kind of stands out because,

  1. We know that it is not valid entity type (unless shadow PK defined but if we want to support that we have to remove this check)
  2. object is base type for every clr type hence it will be set as base type for every other entity type.

This change is not the fix for the user reported exception.
User has property of object type which cannot be mapped by typemapper. Hence user should be notified to exclude it from model since discovering object as entity type throws misleading exception.
For any type other than object, there won't be clr inheritance unless user has defined it using derived class. At which point it is fair to throw above exception notifying user that we have put both entities in same hierarchy by convention (or there is invalid entity type in the model)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ajcvickers I talked to @smitpatel and @AndriySvyryd and right now I understand the reason for this design and I am ok with it. Hopefully I can explain it to you tomorrow before I forget 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@divega After looking through it all again it seems to me that the only real issue is that the original exception message didn't specify that we had pulled "object" into the model. With an appropriate change to the message (possibly more than what is in this PR, although that is a good start) it seems that is all we need to do. In other words, I don't think we also need to special case object. But I look forward to hearing why special casing object is a better thing to do than just having a better exception message for the general case.

@AndriySvyryd
Copy link
Member

:shipit:

@@ -31,7 +31,8 @@ public static Type FindCandidateNavigationPropertyType(this PropertyInfo propert

if (isPrimitiveProperty(targetType)
|| targetType.GetTypeInfo().IsInterface
|| targetType.GetTypeInfo().IsValueType)
|| targetType.GetTypeInfo().IsValueType
|| targetType == typeof(object))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this might be the same thing @divega is saying, but it doesn't seem to me that special casing "object" is the right thing to do here because object is not any more special than any other type that might be the base type for all or some entities in the model,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is special because it is much less likely to be an entity type than any other base type

@smitpatel smitpatel force-pushed the objectAsNavigation branch 2 times, most recently from fe24548 to e5a56b0 Compare November 12, 2015 23:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants