2013-08-02 72 views
1

我有一个实体,名为Task。任务可以有孩子的任务。在我的dal中,我试图每次从我的实体模型中获取任务时自动评估子数。子数不存储在数据库中。定义动态实体属性/函数

例如,让我们来看看我的获取方法:

public TaskDto Fetch(Guid id) 
{ 
    using (var ctx = ObjectContextManager<MyDataContext>.GetManager("MyDataContext")) 
    { 
     var data = (from t in ctx.ObjectContext.Tasks 
        join tty in ctx.ObjectContext.TaskTypes on t.Id equals tty.Id 
        where t.EntityGuid == id 
        select new 
        { 
         Task = t, 
         ChildCount = TaskChildCount(t.EntityGuid) 
        }).FirstOrDefault(); 

     if (data == null) 
     { 
      throw new RecordNotFoundException("Task"); 
     } 

     return ReadData(data.Task, data.ChildCount); 
    } 
} 

但不是调用READDATA与2个PARAMS,我只是想用一个任务参数去调用它:ReadData(data.Task)和ChildCount自动在那里。有什么方法可以将它烘焙到我的任务实体中吗?这是一个很简单的功能:

public int TaskChildCount(Guid currentTaskId) 
{ 
    var ret = 0; 

    using (var ctx = ObjectContextManager<MyDataContext>.GetManager("MyDataContext")) 
    { 
     ret = ctx.ObjectContext.Tasks.Count(x => x.ParentId != currentTaskId); 
    } 

    return ret; 
} 
+1

我不关注。什么是ReadData?你想在你的模型中加入DAL调用?你应该注入一个IRepository对象吗? –

+0

ReadData获取参数(一个任务实体)并返回一个TaskDto - 一个数据合同对象。我不会在我的模型中打dal电话。上面的代码在TaskDal中,通过我的业务层的存储库调用,但这是无关紧要的。 – Kev

+0

如果您的任务具有导航属性,那么您应该能够从传递的任务对象中进行查询。 – Jay

回答

0

有办法做到这一点,但Task总是需要一些帮助。你可以IncludeTask孩子记录:

from t in ctx.ObjectContext.Tasks.Include(t => t.Tasks) 

现在Task可以有一个返回this.Tasks.Count属性TaskCount

您必须在LINQ查询范围之外访问此属性,否则EF将尝试将其转换为SQL并失败。

不足之处在于它填充了家长Task包含的所有Task,这比从数据库中获取计数要重要得多。因此,更好的方法是使用AutoMappers功能按名称约定来投影嵌套属性。假设你TaskDto将有一个属性TasksCount,那么你可以做:

Mapper.CreateMap<Task, TaskDto>(); 
var data = ctx.ObjectContext.Tasks.Project().To<TaskDto>(); 

Project是,AutoMapper可以通过的NuGet获得在AutoMapper.QueryableExtensions扩展方法)。

为简单起见,我省略了joinwhere,但这些都不会改变这个概念。 AutoMapper在Task本身没有找到TasksCount,因此按照惯例,它会尝试找到可应用的属性TasksCount()。它发现儿童收藏Tasks(好吧,也许你以不同的方式命名),然后你就去了。您将看到计数完整地集成在生成的SQL查询中。

区别在于dto是由Fetch方法本身创建的,而不是由ReadData创建的。我无法判断这是否会导致任何问题。也许你必须洗牌一些代码才能使用这个AutoMapper功能。