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

Shared-type entities (part of property bag entities) #9914

Closed
AndriySvyryd opened this issue Sep 27, 2017 · 21 comments · Fixed by #21552
Closed

Shared-type entities (part of property bag entities) #9914

AndriySvyryd opened this issue Sep 27, 2017 · 21 comments · Fixed by #21552
Assignees
Labels
area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. punted-for-3.0 type-enhancement
Milestone

Comments

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Sep 27, 2017

There are entity types that don't have a natural mapping to a CLR type, either because they aren't part of the domain model (e.g. many-to-many join types) or because the CLR types are inaccessible (e.g. migration snapshot). While these could be mapped to shadow entity types #749 that would make working with them harder as they are tightly coupled to the state manager and would need special case handling throughout the stack, especially in the query pipeline.

Property bag entity types are still fully specified at model building time, dynamic types are tracked by #2282. The basic implementation would add support for entities backed up by a Dictionary<string, object> with a predefined entry that contains the entity type name.

Usage:

modelBuilder.Entity("Cat", c =>
    {
        c.Property<int>("Id");
        c.Property<string>("Name");
    });
context.Add(new Dictionary<string, object>
{
    { "Entity type name", "Cat" },
    { "Id", 123 },
    { "Name", "Tabby" }
});

Related to #2968

@ajcvickers
Copy link
Member

Putting this on the backlog for now; we may pull it in if it is needed for some other 2.1 feature, such as if we allow seeding using navigations.

@dmitry-a-morozov
Copy link

This issue seems like slight duplication of #2282. I would like repeat myself saying this feature will be very helpful to implement F# type provider for EF Core. Please, consider bumping up priority. Thanks.

@AndriySvyryd
Copy link
Member Author

@dmitry-a-morozov #2282 is about property bag properties, but this one is about property bag entities, which might or might not contain property bag properties

@dmitry-a-morozov
Copy link

@AndriySvyryd Thanks for clarification. I think I'm interested in this one then. I know statement about F# can be confusing. Let me know if you need more information on why it's helpful for F#.

@divega
Copy link
Contributor

divega commented Oct 16, 2017

@dmitry-a-morozov I believe this would be useful in combination with F# type providers because when the design-time generated types are erased, property bags could act as the runtime type. Is this what you had in mind?

@AndriySvyryd when I wrote the text about property bags in #2282 I was specifically talking about "property bag entities":

Property bags: Currently the EF Core stack assumes a distinct CLR type is mapped to each distinct entity type (and eventually for complex types) in the entity model and a CLR property for each entity property (minus any shadow property). This could be changed to enable EF to materialize and track simple property bags (e.g. any object that implements IDictionary<string, object> or contains an indexer property or any other mechanism to get and set values based on a property name). Even the name of the entity instance belongs to could become another property in the bag. This feature would make working with entity models that are created programmatically easier because it would remove the need to emit new CLR types for each entity and complex type at runtime.

So I am still wondering what you mean when you say these are about two different things 😄

Anyway, I think it is fine to track property bag entities separately here because #2282 is a meta-issue.

@dmitry-a-morozov
Copy link

@divega Great ! I'm glad you're familiar with F# and we're on the same page.
Once it's done F# community can start working on type providers for EF Core.

@dmitry-a-morozov
Copy link

Also, consider working with IDictionary<string, object> interface as oppose to Dictionary<string, object> class so diff implementation can be supplied for example ExpandoObject.

@AndriySvyryd
Copy link
Member Author

AndriySvyryd commented Oct 16, 2017

@divega @dmitry-a-morozov Oops, I was thinking about #2968

@divega
Copy link
Contributor

divega commented Oct 17, 2017

@AndriySvyryd makes sense. Yep, #2968 is closely related too.

Also, consider working with IDictionary<string, object> interface as oppose to Dictionary<string, object> class...

FWIW, I think it could be interesting to support arbitrary types that have an indexer of the right shape rather than requiring a specific type, i.e. pattern match the indexer, but not sure how much more complicated this would be.

@dmitry-a-morozov
Copy link

@divega @AndriySvyryd Any chance you can consider this for 2.1?

@divega
Copy link
Contributor

divega commented Oct 19, 2017

@dmitry-a-morozov there is a possibility that we will do it in 2.1 or soon after, driven by other features like many-to-many without a join entity, but I wouldn't build plans around it just yet.

@cartermp
Copy link

@divega since 2.1 is winding down, is this something we could get on the docket for 2.2?

@divega
Copy link
Contributor

divega commented Feb 12, 2018

@cartermp why don't we try to come up together with a plan to have EF Core work better with F#? Then we can use that to decide the priority of individual issues. I get how this one can help, however there is also #10731, which makes me wonder if we are missing the whole point 😄

@dmitry-a-morozov
Copy link

#10731 is wishful thinking and has no practical value.
F# scaffolding has to be done via Type Providers and currently type providers cannot generate F# records or any other F# specific types for that matter. Currently supported are only .NET 1.1 compatible types. Even generics are not supported. Also many existing and successful type providers do just fine without any F# specific types.

Plan is simple: being able to create erasing F# type providers. Store specific of course.
Except being recommended way to develop type providers erased type provider will have another hidden benefit for EF Core. A type provider must support ad-hoc queries which is ideally done via statically parametrized TP methods which only supported on erased type providers. Any type provider for EF Core that ships without ad-hoc statically typed queries will be unlikely practical for production code.

@AndriySvyryd
Copy link
Member Author

@weitzhandler How is this related to JSON support?

@ajcvickers
Copy link
Member

Marking for re-triage, since we need to pull this into 5.0 and assign as appropriate.

@smitpatel
Copy link
Contributor

smitpatel commented Jun 16, 2020

Pending items here

  • Add model building APIs for relationships as per design meeting discussion
  • Throw error message when using shared type entity types on context based APIs

smitpatel added a commit that referenced this issue Jul 7, 2020
smitpatel added a commit that referenced this issue Jul 8, 2020
@smitpatel smitpatel added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jul 9, 2020
smitpatel added a commit that referenced this issue Jul 15, 2020
- Make FindEntityType(Type) return null for shared type entity type
- Add IModel.IsShared(Type) API
- Flow IEntityType info in places when availble rather than doing Type based loopup

Part of #9914
smitpatel added a commit that referenced this issue Jul 15, 2020
- Make FindEntityType(Type) return null for shared type entity type
- Add IModel.IsShared(Type) API
- Flow IEntityType info in places when availble rather than doing Type based loopup

Part of #9914
@AndriySvyryd
Copy link
Member Author

AndriySvyryd commented Jul 15, 2020

Design meeting decisions:

  • Rename Entity(string, Type) to SharedEntity(string, Type)
  • Add SharedEntity(Type) that just marks the type as shared without creating any entity types. Removes entity types created by convention, throws for entity types configured explicitly
  • Don't add relationship APIs with name and lambda or name and type for now
  • UsingEntity will only create a STET if the CLR type is marked as shared

smitpatel added a commit that referenced this issue Jul 15, 2020
- Make FindEntityType(Type) return null for shared type entity type
- Add IModel.IsShared(Type) API
- Flow IEntityType info in places when availble rather than doing Type based loopup

Part of #9914
smitpatel added a commit that referenced this issue Jul 16, 2020
smitpatel added a commit that referenced this issue Jul 16, 2020
smitpatel added a commit that referenced this issue Jul 17, 2020
@smitpatel smitpatel modified the milestones: 5.0.0, 5.0.0-preview8 Jul 18, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-preview8, 5.0.0-rc1 Aug 22, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-rc1, 5.0.0 Nov 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-model-building closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. punted-for-3.0 type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants