-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
To vs From methods: Proposal to rationalize ToTable, ToQuery, ToView, FromSql, and other related methods #17270
Comments
Note from team: see case in #19708 |
For me, it does not make sense that: context.People.ToList() will return a collection of string?
Did I miss something? |
@alugili - It was mistake. Thanks for pointing out. I updated first post. |
I don't think there's a need to have separate Here's a counter-proposal that just builds on existing API to add more mapping functionality: modelBuilder
.Entity<Blog>()
.ToTable("Blogs", t => t.ExcludeFromMigrations())
.ToView("BlogsView", v =>
{
v.HasDefinitionSql("select * from blogs");
v.IsUpdatable();
})
.FromSql("select * from Blogs")
.ToFunction("GetBlogs", f => f.HasName("get_blogs"))
.UpdateUsingStoredProcedure(u => u.HasName("modify_cust")
.HasParameter(b => b.Id, pb => pb.HasName("customer_id"))
.HasParameter(b => b.Name, pb => pb.IsOutput())
.HasParameter(b => b.AlternateKey)
.HasRowsAffectedParameter(pb => pb.HasName("rows_affected")))
.DeleteUsingStoredProcedure(d => d.HasName("delete_cust")
.HasParameter(b => b.Id, pb => pb.HasName("customer_id")))
.InsertUsingStoredProcedure(i => i.HasName("insert_cust")
.HasParameter(b => b.Id, pb => pb.HasName("customer_id"))
.HasParameter(b => b.Name)
.HasParameter(b => b.AlternateKey)
.HasResultColumn(b => b.Id, rb => rb.HasName("customer_out_id"))
.HasResultColumn(b => b.Name)
.HasRowsAffectedParameter(pb => pb.HasName("rows_affected"))); TPH: modelBuilder.Entity<Blog>()
.ToTable("Blogs")
.HasDiscriminator<string>("blog_type")
.HasValue<Blog>("blog_base")
.HasValue<RssBlog>(null)
.HasNotNull<OtherBlog>(); TPT: modelBuilder.Entity<Blog>().ToTable("Blogs");
modelBuilder.Entity<RssBlog>().ToTable("RssBlogs"); TPC: modelBuilder.Entity<Blog>().ToTable("Blogs")
.InheritPropertyMapping(false)
.Property(b => b.BlogId).HasColumnName("ID");
modelBuilder.Entity<RssBlog>().ToTable("RssBlogs")
.ToTable("RssBlogs", bt =>
{
bt.Property(b => b.BlogId).HasColumnName("id");
}); Table splitting: modelBuilder.Entity<Blog>(b =>
{
b.ToTable("Blogs");
});
modelBuilder.Entity<RssBlog>(b =>
{
b.ToTable("Blogs");
b.HasOne(o => o.Blog).WithOneRequired()
.HasForeignKey<RssBlog>(o => o.BlogId);
}); Entity splitting: modelBuilder.Entity<Blog>(bb =>
{
bb.ToTable("Blogs")
bb.Property(b => b.BlogId).HasColumnName("ID");
bb.Property(b => b.Name).HasColumnName("NAME");
bb.SplitToTable("RssBlogs", m =>
{
m.Property(b => b.BlogId).HasColumnName("Id");
m.Property(b => b.Url);
})
}; |
@AndriySvyryd Similar question here--how much can I do end-to-end in preview 2? |
@ajcvickers Same, only model building and migrations are done so far |
Problems
EnsureCreated
.To
) and ad-hoc mappings in queries (methods start withFrom
). This obviously affects the existing methods but it would be good to have a coherent story if we want to add more, like aFromTable
method you can use directly in queries.Examples
Right now what needs to happen when you call two methods like
ToTable
andToQuery
on the same entity type isn't clear.In general, it is desirable that when and entity is configured with
ToTable
, it affects what the query pipeline, the update pipeline and the DDL pipeline for that entity. But whenToQuery
is also applied, the simplest and most useful behavior seems to be that the latter will only override what happens with the query pipeline.Here the defining query references
People
which is theDbSet<Person>
just to add anOrderBy
call:Ideally this should mean that:
context.People.ToList()
is executed, this will generate the following SQL:For the update pipeline, CUD operations will be generated against
Guests
.In the DDL pipeline (Migrations and EnsureCreated) will still create the table
Guests
. But currently any entity that has a defining query configured is ignored by the DDL pipeline. That is, the table won't be created, and there is no way to override that.There have been similar request from customers to be able to compose
ToTable
andToView
, so that if both are used together, ToView only applies to the query pipeline, andToTable
to the update pipeline and DDL.Proposal
a. We slightly bend the semantics of
To
as used in APIs likeToTable
to specify:b. We start adding
From*
, e.g.FromSql
,FromTable
,FromQuery
,FromView
that are used only to configure the way instances of a type should be retrieved (e.g. the mapping used by the query pipeline), without affecting the other two aspects.c. We add the ability to configuring a null mapping, either through a new API or through calling
ToTable(null)
.d. We add public API to ignore parts of the model in the DDL pipeline (#2725). That is, so that elements can be configured as declared but not defined in the EF Core model. E.g.
IsExtern()
or whatever name we choose.e. We decide what to do with the other existing
To*
methods on a case-by-case basis:ToView
which doesn't allow a definition of the view to be passed, implies by convention to use the same object for the update pipeline and to ignore the object for the purpose of migrations (e.g.IsExtern(true)
).f. For store procedure mapping, also consider how we can leverage the building blocks above. In the past we have got a lot of feedback on the value of having fine-grained mappings, for instance, be able to configure that UPDATEs should go trough a stored procedures while other operations still go through other conventional or explicitly configured mappings. While at the same time, there is value in being able to in a single call configure all CUD operations to stored procedures with by-convention names. But should this override the mapping for the query pipeline, or should we still go by the default table name unless explicitly configured with
FromQuery
orFromSql
?.The text was updated successfully, but these errors were encountered: