1

というエンティティがありTaskます。タスクは子タスクを持つことができます。私のdalでは、エンティティモデルからタスクを取得するたびに子の数を自動的に評価しようとしています。子の数はデータベースに保存されません。

たとえば、私の Fetch メソッドを見てみましょう。

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

しかし、2 つのパラメーターを使用して ReadData を呼び出す代わりに、Task パラメーターを使用して呼び出したいだけでReadData(data.Task)、ChildCount が自動的に存在するようにします。これを Task エンティティに焼き付ける方法はありますか? これは非常に単純な関数です:

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;
}
4

1 に答える 1

0

これを行う方法はありますが、Task常に何らかの助けが必要です。Includeの子レコードを作成できますTask:

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

を返すTaskプロパティを持つことができるようになりました。TaskCountthis.Tasks.Count

LINQ クエリのスコープ外でこのプロパティにアクセスする必要があります。そうしないと、EF はそれを SQL に変換しようとして失敗します。

欠点はTask、parentTaskに含まれるすべての が読み込まれることです。これは、データベースからカウントを取得するよりもはるかに重いです。したがって、より良い方法は、AutoMappers機能を使用して、名前規則によってネストされたプロパティを射影することです。TaskDtoあなたがプロパティを持っていると仮定すると、次のTasksCountことができます:

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

(Projectは の拡張メソッドですAutoMapper.QueryableExtensions。AutoMapper は Nuget を介して取得できます)。

簡単にするためにjoinwhereを省略していますが、これらは概念を変更しません。TasksCountAutoMapperはそれ自体を見つけないため、慣例により、適用できるTaskプロパティを見つけようとします。子コレクション(別の名前を付けた可能性があります) が検索され、そこに移動します。カウントが、生成された SQL クエリにきちんと統合されていることがわかります。TasksCount()Tasks

違いは、dto がFetchではなく、メソッド自体によって作成されることReadDataです。これが問題を引き起こすかどうかは判断できません。この AutoMapper 機能を使用するには、いくつかのコードをシャッフルする必要があるかもしれません。

于 2013-08-02T18:30:41.197 に答える