我需要在C# .NET Core 3.0中更新一个表,该表包含对象列表中的值。我尝试使用Join方法,但收到以下错误:
LINQ表达式的处理
DbSet<Room>
.Join(
outer: __p_0,
inner: p => p.RoomId,
outerKeySelector: s => s.ruId,
innerKeySelector: (s, p) => new {
kuku = s,
riku = p
})
“NavigationExpandingExpressionVisitor”执行的操作失败。这可能表示EF核心中存在错误或限制。有关详细信息,请参阅link。
public class Room
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Key]
public int RoomId { get; set; }
[StringLength(50, MinimumLength = 3)]
public string RoomAddress { get; set; }
}
public class roomsForUpdate
{
public int ruId { get; set; }
public string ruName { get; set; }
}
var roomList = new List<roomsForUpdate>() { new roomsForUpdate { ruId = 1, ruName = "aa" }, new roomsForUpdate { ruId = 2, ruName = "bb" } };
var result = _context.Room.Join(roomList, p => p.RoomId, s => s.ruId, (s, p) => new { kuku = s, riku = p }).ToList();
2条答案
按热度按时间q8l4jmvw1#
无法将EF Core LINQ查询与本地列表联接,因为它无法转换为SQL。最好先获取数据库数据,然后在内存中联接。
uqcuzwp82#
LINQ并不打算更改源,它只能从源中提取数据。如果需要更新数据,请先获取必须更新的项,然后再更新它们。或者,您可以使用普通的旧SQL来更新数据,而不必先获取数据。
在本地内存中,有一个序列
RoomsForUpdate
,每个RoomForUpdate都有一个Id(RuId)和一个Name。在您的数据库中,您有一个
Rooms
表,该表中的每个Room
都有一个RoomId
ID和一个RoomAddress
ID。在我看来,您似乎希望更新所有具有
RoomId
的Rooms
,即RoomsForUpdate序列中的RuIds
之一。换句话说:获取RoomsForUpdate序列中RoomId值为RuId的所有房间(的某些属性):当然,你可以把所有的东西都放到一个大的LINQ语句中。这不会提高效率,但是会降低代码的可读性。
现在要更新Rooms,您必须逐个枚举它们,并为获取的Rooms赋予新值。您没有说您想要哪个新值。我有一种暗示,您想要将RuName赋给RoomAddress。这意味着您必须将Room与RoomAddress的新值组合在一起。
这可以通过LINQ完成:
要实际执行更新,您必须枚举以下序列:
少一点LINQ
虽然这是可行的,但似乎有很多魔法在进行。连接将在内部创建一个用于快速查找的字典,并将其丢弃。我认为少一点LINQ将使理解发生了什么更容易。
字典的关键字是您要获取的房间的ID: