Быстрый комментарий к дизайну:
Я не большой поклонник обнуляемых значений в базе данных, особенно , когда null
предоставляет контекстную информацию, такую как значение, применяемое к всем пользователям, в отличие от нет пользователей.
Возможно, вы захотите рассмотреть проект, в котором вы можете группировать пользователей, и теги будут видны группе пользователей. Это будет более гибким в случае изменения ваших потребностей в будущем и более явным. Это также сделает так, что вы можете сделать столбец не обнуляемым.
Если вы не хотите встраивать это в свою систему сейчас, я бы лично представил, как будет выглядеть переход от вашего текущего дизайна к дизайну на основе группы, просто чтобы убедиться, что вы не нарисовали себя в угол по дизайну.
Проблема под рукой
Вы получаете AllTags
из контекста, поэтому вам придется использовать объект контекста.
Попытка 1
Один из способов сделать это - создать метод в контексте, который принимает User
или UserId
.
// In partial Context class...
public IEnumerable<Tag> GetVisibleTags(User user)
{
return Tags.Where(t => t.PrivateUserID == null)
.Union(user.Tags)
;
}
// Call it like this...
context.GetVisibleTags(someUser);
Мне не совсем нравится, потому что я не думаю, что контекст должен использоваться для выполнения запросов. Это работа для «хранилища» (сущность / DbSet
/ DataSet
класс).
Попытка 2
Другим способом (который сделает его доступным для пользователя) будет добавление параметра контекста в ваш метод получения:
// In partial User class...
public IEnumerable<Tag> GetVisibleTags(MyContextClass context)
{
return context.Tags.Where(t => t.PrivateUserID == null)
.Union(this.Tags)
;
}
// Call it like this
someUser.GetVisibleTags(context);
Мне нравится это даже меньше, чем первое, потому что "хранилищу" (entity / DataSet
/ DbSet
) нельзя разрешать ничего знать о контексте.
Попытка 3
Вы можете создать объект-оболочку запроса, чтобы решить эту проблему. Обычно я советую вам писать сложные запросы, когда это возможно, чтобы их можно было многократно использовать.
Хитрость заключается в том, чтобы выяснить хорошее имя домена для класса ...
// Todo: This is a terrible name.
// Figure out what makes more sense in your domain, by seeing where you use it
public class VisibleTags
{
private readonly IMyContextClass context;
public VisibleTags(IMyContextClass context)
{
this.context = context;
}
// Todo: Try to see if you can get this to return IQueryable.
// I haven't used Union, so I'm not sure if it breaks that ability or not...
public IEnumerable<Tag> GetVisibleTags(User user)
{
return context.Tags
.Where(t => t.PrivateUserID == null)
.Union(user.Tags)
;
}
}