У меня есть модель со связанным списком внешних ключей, т. Е.
[Table("a"]
public class A {
[Key]
[Column("a_id")]
public int Id { get; set; }
public List<B> Bs { get; set; } = new List<B>();
}
[Table("b"]
public class B {
[Key]
[Column("b_id")]
public int Id { get; set; }
[NotMapped]
public string MyFunctionValue { get; set; }
[ForeignKey("a_id")]
public A A { get; set; }
}
Затем я определил функцию, которая ссылается на скалярную функцию sql следующим образом ...
public static class MySqlFunctions {
[DbFunction("MyFunction", "dbo")]
public static string MyFunction(int bId) {
throw new NotImplementedException();
}
}
и зарегистрирован в моем контексте следующим образом ...
modelBuilder.HasDbFunction(() => MySqlFunctions.MyFunction(default));
То, что я хочу иметь в своем классе репозитория, - это захватить записи A со связанными записями B в списке с их MyFunctionValueзначение устанавливается равным возвращаемому значению функции при запуске с идентификатором B. Что-то вроде ...
myContext.A
.Include(a => a.Bs.Select(b => new B {
Id = b.Id,
MyFunctionValue = MySqlFunctions.MyFunction(b.Id)
});
Однако со всеми опциями, которые я пробовал до сих пор, я получаю либо InvalidOperationException, либоNotImplementedException Я полагаю, потому что он не может должным образом преобразовать его в SQL?
Можно ли как-нибудь написать такой запрос или он слишком сложен для EF, чтобы генерировать SQL?Я знаю, что есть вероятность, что я мог бы использовать .FromSql, но я бы предпочел избежать этого, если это возможно, потому что это немного грязно.
РЕДАКТИРОВАТЬ:
Так что мне удалосьзаставить его работать со следующим кодом, но он, очевидно, немного запутан, если у кого-то есть лучшее решение, я был бы благодарен.
myContext.A
.Include(a => a.Bs)
.Select(a => new {
A = a,
MyFunctionValues = a.Bs.Select(b => MySqlFunctions.MyFunction(b.Id))
})
.AsEnumerable()
.Select(aWithMfvs => {
for (int i = 0; i < aWithMfvs.MyFunctionValues.Count(); i++) {
aWithMfvs.A.Bs[i].MyFunctionValue = aWithMfvs.MyFunctionValues[i];
}
return aWithMfvs.A;
})
.AsQueryable();