我在EF Core中寻求与此SQL查询等效的内容:
SELECT Id, Name, (Select AdminRoleId From EventAdmins Where EventId = Events.Id And AdminId = [value from cookie]) As EventRoleId From Events
这是我到目前为止所拥有的:
public IList<Event> Events { get; set; }
public IList<EventAdmin> EventAdmins { get; set; }
public async Task<IActionResult> OnGetAsync() {
var adminId = Guid.Parse(Request.Cookies["Adm_AdminId"]);
Events = await _context.Events.SelectMany(e => e.EventAdmins.Where(x => x.EventId == e.Id && x.AdminId == adminId).Select(x => x.AdminRoleId)).AsNoTracking().ToListAsync();
return Page();
}
我不确定出什么问题,但是我收到一条错误消息:“错误CS0452:类型'Guid'必须是引用类型,才能在通用类型或方法中将其用作参数'TEntity'”。 / p>
事件模型:
public class Event {
public Guid Id { get; set; }
public string Name { get; set; }
[ForeignKey("Id")]
public IList<EventAdmin> EventAdmins { get; set; }
}
EventAdmin模型:
public class EventAdmin {
public Guid Id { get; set; }
public Guid EventId { get; set; }
public Guid AdminId { get; set; }
public Guid AdminRoleId { get; set; }
[ForeignKey("EventId")]
public Event Events { get; set; }
}
答案 0 :(得分:1)
发生此错误是因为您试图让EF Core不跟踪GUID
的列表。但是,Guid列表是值类型的列表。
您知道,EF Core只能跟踪一系列引用类型,因此method signature of AsNoTracking<TEntity>()
为:
public static IQueryable<TEntity> AsNoTracking<TEntity> (this IQueryable<TEntity> source)
where TEntity : class;
请注意 where TEntity : class
的约束。
换句话说,您永远无法调用AsNoTracking<Guid>()
:
Events = await _context.Events
.SelectMany(e => e.EventAdmins.Where(x => x.EventId == e.Id).Select(x => x.AdminRoleId))
.AsNoTracking() // Actually, it will invoke `AsNoTracking<Guid>()`
.ToListAsync();
您的SQL似乎无效。我猜您想返回一个{Id, Name, EventRoleId}
。
如果您想使用SelectMany
进行此操作,只需按以下方式查询:
var Events = await this._context.Events
.SelectMany(
e => e.EventAdmins.Where(x => x.EventId == e.Id).Select(x => x.AdminRoleId),
(p,g) => new {
Id = p.Id,
Name = p.Name,
EventRoleId = g
}
)
// .AsNoTracking()
.ToListAsync();
根本不需要致电.AsNoTracking()
。因为如果结果集不包含任何实体类型,则不执行跟踪。
请注意,您不应该使用Event.EventAdmins
属性修饰[ForeignKey("Id")]
:
public class Event { public Guid Id { get; set; } public string Name { get; set; }[ForeignKey("Id")]public IList EventAdmins { get; set; } }
因为Event
是主体实体,EventAdmin
是从属实体。仅EventAdmin
具有引用Event
的外键。
答案 1 :(得分:0)
您的LINQ查询似乎未包含adminId,因此我看不到它如何工作。尝试这样的事情:
var eventAdmin = _context.EventAdmin.SingleOrDefault( e => e.Id == adminId);
var events = eventAdmin.Events;
尝试使用类似Linqpad的工具一次将查询分解。