0

我有这个域模型,

class UserInfo{
    int UserId{get;set;}
    string UserName{get;set;}
    IList<Task> Tasks{get;set;}
}

class Task{
    int TaskId{get;set;}
    string TaskName{get;set;}
    UserInfo AssignedTo{get;set;}
}

class UserMap: ClassMap<UserInfo>
{ 
    public UserMap()
    {
        Id(x=>x.UserId);
        Map(x=>x.UserName)
        HasMany(x=>x.Tasks);
    }
 }

现在,一个用户可能有任意数量的任务分配给他,但 Active 总是没有或只有一个。这存储在另一个表中并通过另一个实体定义。因此,如果有一个孩子的活动任务,则 ActiveTask 表中存在一条记录。

class ActiveTask{
    int Id{get;set;}
    int UserId{get;set;}
    int TaskId{get;set;}
    datetime CreatedOn{get;set;}
}

问题,

  • 如何使用 USERINFO 映射 ACTIVETASK
  • 我想获取用户列表以及活动任务(如果有)。

请建议如何做

4

1 回答 1

0

我认为您很难找到一个好的答案,因为这将取决于其他因素,例如您希望给定用户拥有的任务数量。也就是说,听起来您正在尝试使用单个集合Task并将其标记为活动。从领域的角度来看,我敢打赌这就是现实。人有很多任务,一个是主动的。活动任务仍然是任务。

如果是这种情况,那么一种选择是向IsActive您的对象添加一个属性Task,然后将映射中的获取策略设置为急切(否则您将遇到 select n+1 问题)。然后,您的ActiveTask属性可以使用 linq 选择Task集合中具有Active == true.

如果你走这条路,那么你会想在你的类中添加逻辑以将任务设置为活动状态,以便将所有其他任务设置为非活动状态。像这样的东西:

class UserInfo
{
    public virtual int UserId{get;set;}
    public virtual string UserName{get;set;}
    public virtual IList<Task> Tasks{get;set;}

    public virtual Task ActiveTask
    {
        get
        {
            return Tasks.FirstOrDefault(t => t.IsActive == true);
        {
    }

    public void SetActive(Task task)
    {
        // Set all tasks to inactive
        // Set the task in question to active
    }
}

如果是我,我可能还会将Tasks集合从自动属性更改为具有支持字段并protected internal用于设置,以便您可以确保仅在映射期间分配列表。

请注意,如果您有大量用户或任务,那么 Eager fetch 策略可能会变得昂贵。在这种情况下,您可能希望使用单独的表来跟踪哪个任务处于活动状态并以这种方式进行映射。

更新

我回去检查了我做过的其他一些有类似要求的项目,在一种情况下,我实际上更改了它,因此父对象持有对活动子对象的引用。因此,您UserInfo在数据库中的表将有一个 FK 列,ActiveTask_Id该列与Task表的 PK 相关。然后您的用户映射将是(假设您正在覆盖自动映射):

public class UserInfoOverride : IAutoMappingOverride<UserInfo>
{
    public void Override(AutoMapping<UserInfo> mapping)
    {
        mapping.References(x => x.ActiveTask).Fetch.Join();
    }
}

然后,您只需将任务设置为对象的ActiveTask属性UserInfo并保存。

于 2013-09-17T13:29:46.387 回答