0

I have existing table in my db and need create a domain for it to work with existing data.

I have next tables structure:

Application
'ORDERSCANNER'

ApplicationFunction
'ORDERSCANNER','SCAN'
'ORDERSCANNER','READ'
'ORDERSCANNER','PRINT'

FunctionalGroup
'ADMIN','RUS','ORDERSCANNER','SCAN'
'ADMIN','RUS','ORDERSCANNER','PRINT'
'ADMIN','JAP','ORDERSCANNER','SCAN'
'ADMIN','JAP','ORDERSCANNER','PRINT'
'OPERATOR','RUS','ORDERSCANNER','SCAN'
'OPERATOR','JAP','ORDERSCANNER','SCAN'

User
'IVANOV','RUS','OPERATOR'
'PETROV','RUS','OPERATOR'
'PETROV','JAP','OPERATOR'
'SIDOROV','RUS','ADMIN - he is an ADMIN group but only for RUS. He is not able to scan for JAP

Here is how I see my domain

public class Application // root
{
    private readonly List<ApplicationFunction> _functions;
    public string ApplicationId { get; set; }

    public Application()
    {
        _functions = new List<ApplicationFunction>();
    }
    public void AddFunction(string newFunction)
    {
        var function = new ApplicationFunction(this, newFunction);
        _functions.Add(function);
    }
}
public class ApplicationFunction // value object
{
    public Application Application { get; private set; }
    public string FunctionId { get; private set; }

    public ApplicationFunction(Application application, string functionId)
    {
        if (application == null) throw new ArgumentNullException("application");
        if (functionId == null) throw new ArgumentNullException("functionId");
        Application = application;
        FunctionId = functionId;
    }
}
public class FunctionalGroup // root
{
    private readonly List<ApplicationFunction> _functions;
    public string GroupId { get; set; }
    public string MarketingPlanCode { get; set; }
    public IEnumerable<ApplicationFunction> Functions { get { return _functions; } }

    public FunctionalGroup()
    {
        _functions = new List<ApplicationFunction>();
    }
    public void AddFunction(ApplicationFunction applicationFunction)
    {
        _functions.Add(applicationFunction);
    }
}
public class User // root
{
    private readonly List<FunctionalGroup> _groups;
    public string UserId { get; set; }
    public IEnumerable<FunctionalGroup> Groups { get { return _groups; } }

    public User()
    {
        _groups = new List<FunctionalGroup>();
    }
    public void AddToGroup(FunctionalGroup functionalGroup)
    {
        _groups.Add(functionalGroup);
    }
}

Let's look at User.

public class UserMap : ClassMap<User>
{
     public UserMap()
     {
         Id(x => x.UserId).Column("USER_ID");
         HasMany(x => x.Groups).Cascade.All();
     }
}

Looks like I need extra data to map from my collection of FunctionalGroup - it's MarketingPlanCode. If I'll add MarketingPlanCode property to my User class I'll get only one property per collection. But I need I property per item in that collection.

Well If I couldn't explain what I need Just take a look at the example data from my tables. Is there any way to map it?

Akim Khalilov
  • 1,019
  • 4
  • 16
  • 31
  • do Functions represent logic where each function executes different code? some kind of Strategy pattern? – Firo Oct 26 '12 at 10:00

1 Answers1

1

i think the model could be simplified further but first ditch FunctionalGroup class completely.

public ApplicationFunctionMap()
{
    CompositeId()
        .KeyReference(x => x.Application, "application_id")
        .KeyProperty(x => x.FunctionId, "FunctionId");
}

public UserMap()
{
    Component(x => x.Group, c => 
    {
        c.Map(g => g.Name, "GroupId");
        c.Map(g => g.MarketingPlanCode, "MarketingPlanCode");
    })

    HasManyToMany(x => x.AllowedFunctions)
        .Table("FunctionalGroup")
        .ParentKeyColumns.Add("GroupId", "MarketingPlanCode") // in FunctionalGroup table
        .ChildKeyColumns.Add("application_id", "FunctionId") // in FunctionalGroup table
        .Propertyref(x => x.Group);   // Component defined above
}
Firo
  • 30,626
  • 4
  • 55
  • 94
  • Ok, I got your idea about components, but not with collections. What does this mean? And where is Id for UserMap? – Akim Khalilov Oct 26 '12 at 22:35
  • i left out the id because it doesn't influence the HasManyToMany mapping. The FunctionalGroup table is a link table with compositeIds and with NHibernate you wont need a class for it. You'll just need to map the foreign key columns for the parent and the child and since the join to the parent does not use the primary key/id i used PropertyRef. Try it and tell us if it works – Firo Oct 27 '12 at 18:40