繁体   English   中英

如何在实体框架的部分类中包含不相关的实体?

[英]How can I include non-related entities in partial classes in entity framework?

我正在尝试将部分类中的属性添加到实体框架模型,该模型包括通过导航属性与一些附加行结合的实体。

数据库:我有一个带用户ID主键的用户表。 另外,我有一个带有OwnerUserID(外键,可为空)的标签表,如果它是用户特定的,则将其设置为UserID,但也可能为null以指示它适用于所有用户。

EF模型:正确生成了导航属性Users.Tags,以包括显式分配给该用户的所有标签。

问题:我需要用户实体上的属性,该属性包括所有具有用户的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}代表系统中的所有标签。

关于设计的简短评论:

我不是数据库中可空值的忠实拥护者, 尤其是null提供上下文信息时,例如适用于所有用户的值而不是没有用户的值。

您可能需要考虑一种可以对用户进行分组的设计,并且标签对一组用户可见。 如果将来您的需求发生变化,这将更加灵活,并且更加明确。 它还可以使列变为不可为空。

如果您现在不想将其构建到您的系统中,我将亲自列出从当前设计到基于组的设计的迁移情况,以确保您不会陷入困境。设计方面。

眼前的问题

您从上下文中获取AllTags ,因此您将不得不使用上下文对象。

尝试1

一种实现方法是在上下文中创建一个接受UserUserId

// 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

另一种方法(使用户可以访问它)是将上下文参数添加到您的getter方法中:

// 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)
            ;
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM