I'm writing a IQueryable<T>
extension method and I would like to get the foreign keys of the navigation properties of T
. I have figured out that I can get access to them through IModel.FindEntityType(T).GetNavigations()
, the question is how to best get access to the IModel
while keeping the method as simple as possible.
At the moment the method looks something like this:
public static IQueryable<TQuery> DoMagic<TQuery>(this IQueryable<TQuery> query, IModel model)
{
var entity = model.FindEntityType(entityType);
var navigationProperties = entity.GetNavigations();
...
}
I would love if I wouldn't need to pass IModel
as an argument like this:
public static IQueryable<TQuery> DoMagic<TQuery>(this IQueryable<TQuery> query)
{
var entity = Model.FindEntityType(entityType);
var navigationProperties = entity.GetNavigations();
...
}
I have considered adding a IServiceCollection
extension method and passing the DbContext
and setting IModel
as a static property to the IQueryable<T>
extension method. The problem with that is that it is limiting me to one DbContext
.
I have also looked into the option to add a extension method to DbContextOptionsBuilder
but haven't really figured out best way to achieve what I want to do this way.
Maybe there is other ways to get access to the foreign keys? Any help is greatly appreciated!
Edit
From the navigation properties I want to access the ForeignKey
-property to know what property is used to resolve the navigation property. Something like:
navigationProperties.ToList().Select(x => x.ForeignKey);
One way of getting the navigation properties:
public static IQueryable<TQuery> DoMagic<TQuery>(this IQueryable<TQuery> query)
{
var navigationProperties = typeof(TQuery).GetProperties()
.Where(p => (typeof(IEnumerable).IsAssignableFrom(p.PropertyType) && p.PropertyType != typeof(string)))
.ToArray();
...
}
UPDATE:
Trying to get DbContext
which has the Model
property from IQueryable
would result in some not pretty code, this link shows how it could be done:
.Net EF Core 2.1 Get DbContext from IQueryable argument
If you are using dependency injection, you could put the instance of DbContext into the container in the scope of the web request or the operation and inject it into the class with the DoMagic
method.
Another way could to add the method to the descendant of DbContext
class, then the model parametere would not be needed.