Как я могу включить несвязанные сущности в частичные классы в структуре сущностей? - PullRequest
0 голосов
/ 11 ноября 2011

Я пытаюсь добавить свойство в частичном классе в модель платформы сущностей, которая включает сущности, которые были сопоставлены через свойства навигации, объединенные с некоторыми дополнительными строками.

База данных: У меня есть таблица Users с первичным ключом UserID.Кроме того, у меня есть таблица тегов с OwnerUserID (внешний ключ, обнуляемый), для которого задано значение UserID, если оно зависит от пользователя, но также может быть и значение NULL, указывающее, что оно применимо ко всем пользователям.

EF Модель: Правило навигации Users.Tags сгенерировано правильно, чтобы включить все теги, которые явно назначены этому пользователю.

Проблема: Мне нужно свойство для сущности User, которое включает в себя все теги, которые имеют OwnerUserID пользователя и те, которые являются нулевыми.Поэтому я хочу сказать что-то вроде:

public partial class User
    {
        public IEnumerable<Tag> VisibleTags
        {
            get
            {
                return tags = (from t in {AllTags}
                                where t.PrivateUserID == null
                                select t).Union(
                                from t in this.Tags
                                select t);
            }
        }
    }

... где {AllTags} представляет все теги в системе.

1 Ответ

3 голосов
/ 11 ноября 2011

Быстрый комментарий к дизайну:

Я не большой поклонник обнуляемых значений в базе данных, особенно , когда 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)
            ;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...