简体   繁体   中英

Alternative to mapping a dictionary of lists?

I have a simple schema that looks like this:

The idea is that there are Users, Departments and Flows. For each Department, a User can "star" multiple Flows to "bookmark" them (therefore Department/User pair can have many Flows).

Ideally, I'd like to use the following classes:

public class User
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
}

public class Department
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }
    public virtual IDictionary<User, IList<StarredFlow>> StarredFlows { get; protected set; }

    public Department()
    {
        this.UserStarredFlows = new Dictionary<User, IList<StarredFlow>>();
    }
}

public class Flow
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; set; }

    protected Flow() { }
}

public class StarredFlow
{
    public virtual int Id { get; protected set; }
    public virtual User User { get; protected set; }
    public virtual Department EntryPoint { get; protected set; }
    public virtual Flow Flow { get; protected set; }
    public virtual string Name { get; protected set; }

    protected StarredFlow() { }

    public StarredFlow(User user, Department ep, Flow flow, string name)
    {
        this.User = user;
        this.EntryPoint = ep;
        this.Flow = flow;
        this.Name = name;
    }
}

This would allow pretty literal code:

var userStarredFlowsForDepartment = department.StarredFlows[currentUser];

However, NHibernate doesn't support mapping dictionaries of lists. I found a similar question/answer that involves moving the IList<StarredFlow> to a new class and mapping it using a component. Sadly, FluentNHibernate doesn't support doing collection mapping with components (there's no HasMany off of the component mapping).

This seems like a trivial thing to do with an NHibernate, but I'm struggling to find a solution. Is there a better solution to doing this? I'd really like to not have to resolve to just using session.Save(starredFlow) and Query<StarredFlow>() because they move the logic outside of the models.

What you want to do is definitely not supported. I'm not saying it wouldn't be a theoretically valid design, but NHibernate does not support it and it's unlikely that it will do so in the future.

That said, you can always have a method in Department instead of a dictionary, taking an IQueryable :

public IEnumerable<StarredFlow> GetUserStarredFlows(IQueryable<StarredFlow> source,
                                                    User user)
{
    return source.Where(x => x.User == user)
                 .ToList(); //you could skip this depending on your usage
}

Or (a bit more complex) you could inject the IQueryable or the session.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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