How to include related entities in an Entity Framework Core 1.0.1 raw query?

asp.net-core dbcontext entity-framework entity-framework-core mysql

Question

Setup:

  • ASP .NET Core 1 Web API

  • MySQL Server Community Edition 5.7

  • Entity Framework Core 1.0.1 with Pomelo MySQL driver (3 separate contexts, 3 separate databases).

Contexts: MainContext (maindb), Module1Context (module1db), Module2Context (module2db).

I want to execute a query that returns a list of Posts (from Module1Context), but I need to filter them by author rights (from MainContext, User entity).

So, what I am trying to do is execute a query with a JOIN clause to a different database table:

var results = await module1Ctx.Posts.FromSql("select * from `module1db`.`posts` as `p` inner join `maindb`.`users` as `u` on `p`.`AuthorId`=`u`.`Id` where <conditions here>").ToListAsync();

When this executes, I get a SQL Exception telling me that "Sequence contains more than one element". If I select p.*, it will work, but I also need to pull the user data.

The Post entity contains a reference to the user ID (public long AuthorId {get;set;}), and a fake navigation property, NotMapped, as EF couldn't join 2 databases automatically. My first question is - would this be possible. I have a strong feeling that this will work, but that I am missing something small.

If this doesn't work, I will resort to manually executing the query, using the DbContext's Connection. If I will do this, how can I map the results into a list of Posts, including the User data?

1
1
10/8/2016 12:53:04 PM

Accepted Answer

Sequence contains more than one element

This tells you that a column appears more than once. For example if you have "ModifiedDate" column in both tables, when you do select * it will appear twice in the result set (once p.ModifiedDate and once in u.ModifiedDate.

Also additional to this, the columns returned must exactly match the model. No property which is defined in the model must be missing, that's why p.* will work.

But unless your Post model does define fields which represent values from User table, you can't return them, because it must exactly match Post and it's mapped properties.

Ad-hoc support (mapping result to an arbitrary model, like a view model) is not yet implemented in EntityFramework Core 1.0 and is a feature on the roadmap for future versions.

From the EntityFramework Core Roadmap:

Critical O/RM features

  • ...
  • Raw SQL queries for non-Model types allows a raw SQL query to be used to populate types that are not part of the model (typically for denormalized view-model data).

Edit

Also from the EFCore documentation

Limitations

There are a couple of limitations to be aware of when using raw SQL queries:

  • SQL queries can only be used to return entity types that are part of your model. There is an enhancement on our backlog to enable returning ad-hoc types from raw SQL queries.
  • The SQL query must return data for all properties of the entity type.
  • The column names in the result set must match the column names that properties are mapped to. Note this is different from EF6.x where property/column mapping was ignored for raw SQL queries and result set column names had to match the property names.
  • The SQL query cannot contain related data. However, in many cases you can compose on top of the query using the Include operator to return related data (see Including related data).
3
10/8/2016 1:00:41 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow