Это моя модель:
- Business
- BusinesType - FK
- Categories (*) - FK
- Branch (*)
- BranchType - FK
- Address
- Phone (*)
- CustomFields (*)
- OpeningTimes (*)
- WorkingPeriods (*)
- .....
Теперь у меня есть действие-контроллер, которое принимает форму, состоящую из целого набора данных как единого объекта Business
со всеми его свойствами и наборами, которые установлены в порядке.
Теперь мне нужно пройти через все свойства и коллекции рекурсивно и сравнить с графом базы данных; если они не существуют, добавьте их, если они снова пройдут через все свойства и выполняют их на более глубоком уровне до тех пор, пока свойства навигации не останутся. Поскольку у меня есть еще много свойств и потомков, чем указано в предыдущем примере, он просто внутри, чтобы пройти через них вручную.
Благодаря этому ответу я нашел GraphDiff, который предложил блестящее решение этой ситуации.
Здесь запрос обновления, который я вызываю:
Context.UpdateGraph(business, bus => bus
.AssociatedEntity(bu => bu.BusinessType)
.AssociatedCollection(bu => bu.Categories)
.OwnedCollection(bu => bu.Branches, branch => branch
.AssociatedEntity(b => b.BranchType)
.OwnedEntity(b => b.Address)
.OwnedCollection(b => b.Phones)
.OwnedCollection(b => b.CustomFields)
.OwnedCollection(b => b.OpeningTimes, openingTimes => openingTimes
.OwnedCollection(b => b.WorkingPeriods)
)
)
);
Он выдает это исключение:
System.InvalidCastException: Невозможно передать объект типа "System.Linq.Expressions.MethodCallExpressionN" для ввода "System.Linq.Expressions.MemberExpression".
Я попытался отлаживать исходный код, но я не эксперт с деревьями выражений, проблема возникает, когда внутренний вызов Include
(чтобы включить граф объектов для загрузки объекта хранилища) пытается подключить WorkingPeriods
, выглядит он не готов принять тот уровень глубины рекурсии. Я немного перепутал это, но я уверен, что кто-то с обширными знаниями в деревьях выражений сможет легко решить эту проблему. Любые предложения будут оценены по этому поводу.
Здесь предполагается, что выражение include path должно быть сгенерировано следующим образом:
.Include(b =>
b.Branches.Select(br =>
br.OpeningTimes.Select(ot =>
ot.WorkingPeriods)));
По сути, исключение вызывается, потому что рекурсивный вызов возвращает внутреннее включение как вызов метода, без его обработки и возврата свойства коллекции, которое оно предназначено для раскрытия.