无法从 kendo 网格的右手 table 获取多对多导航到 return 数据的剃刀页面
Cant get a razor page many to many navigation to return data from the right hand table for a kendo grid
不确定我说的对不对,但我在 net core 3.1 中有一个 razor pages 业务应用程序,有很多多对多连接。我目前正在处理一个连接并尝试通过存储库调用将结果提供给 kendo 网格
以下是示例的模型,由 "NoteNoteTypeJoins"
加入 "Notes" 和 "NoteTypes"
public class Note
{
public int ID { get; set; }
[Display(Name = "Short Title")]
[Required]
public String Title { get; set; }
[Display(Name = "Note Content")]
public String NoteText { get; set; }
public int UserID { get; set; }
//some fields left out for brevity
public ICollection<NoteStaffJoin> NoteStaffJoins { get; set; }
public ICollection<NoteClientJoin> NoteClientJoins { get; set; }
public ICollection<NoteOrgJoin> NoteOrgJoins { get; set; }
public ICollection<NoteNoteTypeJoin> NoteNoteTypeJoins { get; set; }
}
public class NoteNoteTypeJoin
{
public int NoteNoteTypeJoinID { get; set; }
public int NoteID { get; set; }
public int NoteTypeID { get; set; }
public DateTime? Saved { get; set; }
public int? UserID { get; set; }
public Note Note { get; set; }
public NoteType NoteType { get; set; }
}
public class NoteType
{
public int ID { get; set; }
public string Type { get; set; }
public int? ParentID { get; set; }
public int? NoteTypeGroupID { get; set; }
public int? DisplayOrder { get; set; }
public int? UserID { get; set; }
public ICollection<NoteNoteTypeJoin> NoteNoteTypeJoins { get; set; }
}
public FliveRetryContext(DbContextOptions<FliveRetryContext> options)
: base(options)
{
public DbSet<FliveRetry.Models.Note> Note { get; set; }
public DbSet<FliveRetry.Models.NoteType> NoteType { get; set; }
public DbSet<FliveRetry.Models.NoteNoteTypeJoin> NoteNoteTypeJoin { get; set; }
}
据 ef core 所见,外键等都已正确定义
CREATE TABLE [dbo].[NoteNoteTypeJoin] (
[NoteNoteTypeJoinID] INT IDENTITY (1, 1) NOT NULL,
[NoteID] INT NOT NULL,
[NoteTypeID] INT NOT NULL,
[Saved] DATETIME2 (7) NULL,
[UserID] INT NULL,
CONSTRAINT [PK_NoteNoteTypeJoin] PRIMARY KEY CLUSTERED ([NoteNoteTypeJoinID] ASC),
CONSTRAINT [FK_NoteNoteTypeJoin_Note_NoteID] FOREIGN KEY ([NoteID]) REFERENCES [dbo].[Note] ([ID]) ON DELETE CASCADE,
CONSTRAINT [FK_NoteNoteTypeJoin_NoteType_NoteTypeID] FOREIGN KEY ([NoteTypeID]) REFERENCES [dbo].[NoteType] ([ID]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_NoteNoteTypeJoin_NoteID]
ON [dbo].[NoteNoteTypeJoin]([NoteID] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_NoteNoteTypeJoin_NoteTypeID]
ON [dbo].[NoteNoteTypeJoin]([NoteTypeID] ASC);
上周我已经尝试了网络上的所有示例,但无法正确使用。我最终使用连接 table 中的 ID 使其工作,不需要调用 NoteTypes table:
public async Task<List<Note>> GetAllNotesForNoteTypeIDAsync(int notetypeid)
{
var noteData = await context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteTypeID == notetypeid))
.ToListAsync();
return noteData;
}
我必须将此引用循环处理选项添加到 startup.cs 才能使包含工作,感谢 Telerik 提供的信息:
services.AddRazorPages().AddNewtonsoftJson
(options => {
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
这同样有效,只查询左手 table,即使包括其他人:
public async Task<List<Note>> GetAllNotesForUserAsync(int userId)
{
var noteData = await context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.UserID == userId)
.ToListAsync();
return noteData;
}
我想按 NoteType 文本而不是 ID 进行搜索,因为不同版本的 ID 可能不同。
这就是我目前所拥有的,但它使页面崩溃,就像许多其他变体一样:
public async Task<List<Note>> GetAllNotesForNoteTypeAsync(string notetype)
{
var noteData = await context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteType.Type.ToString() == notetype))
.ToListAsync();
return noteData;
}
此崩溃并显示以下消息:
An unhandled exception occurred while processing the request.
InvalidOperationException: The LINQ expression 'DbSet<NoteNoteTypeJoin>
.Where(n0 => EF.Property<Nullable<int>>((EntityShaperExpression:
EntityType: Note
ValueBufferExpression:
(ProjectionBindingExpression: EmptyProjectionMember)
IsNullable: False
), "ID") != null && EF.Property<Nullable<int>>((EntityShaperExpression:
EntityType: Note
ValueBufferExpression:
(ProjectionBindingExpression: EmptyProjectionMember)
IsNullable: False
), "ID") == EF.Property<Nullable<int>>(n0, "NoteID"))
.Join(
outer: DbSet<NoteType>,
inner: n0 => EF.Property<Nullable<int>>(n0, "NoteTypeID"),
outerKeySelector: n1 => EF.Property<Nullable<int>>(n1, "ID"),
innerKeySelector: (o, i) => new TransparentIdentifier<NoteNoteTypeJoin, NoteType>(
Outer = o,
Inner = i
))
.Any(n0 => n0.Inner.Type.ToString() == __notetype_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
我也没有对最后加入的智能感知访问权限,这阻止了我在论坛上使用很多建议,所以像 .Where(n => n.NoteNoteTypeJoins.Type == notetype)) 这样的东西'不可用,因为 .Type 在 NoteNoteTypeJoins 之后不可用。
这些是我需要过滤的四个多对多关系:
Note = await _context.Note
.Include(i => i.NoteOrgJoins).ThenInclude(i => i.Org)
.Include(i => i.NoteClientJoins).ThenInclude(i => i.Client)
.Include(i => i.NoteStaffJoins).ThenInclude(i => i.Staff)
.Include(i => i.NoteNoteTypeJoins).ThenInclude(i => i.NoteType)
如果有人可以建议一个有效的导航调用而不是加入,那至少可以让我摆脱笔记类型调用的麻烦,我会很兴奋,如果你能告诉我如何添加其他调用好吧,那会更好。我仍在学习 C# 和剃刀,所以它可能是调用本身之外的东西,但我试图坚持标准设置。
感谢大家
I also don't have intellisense access to the last join, which is stopping me using a lot of suggestions on forums so something like .Where(n => n.NoteNoteTypeJoins.Type == notetype)) isn't available because .Type isn't available after NoteNoteTypeJoins.
原因是 EF Core 3 中禁用了隐式客户端计算。
参考:
您可以像下面这样更改您的代码:
var noteData = await _context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.ToListAsync();
var d = noteData.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteType.Type.ToString() == notetype))
.ToList();
另一种方式是你的NoteType
class中的Type
属性是string.No的类型需要使用ToString()
方法:
var noteData = await _context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteType.Type == notetype))
.ToListAsync();
不确定我说的对不对,但我在 net core 3.1 中有一个 razor pages 业务应用程序,有很多多对多连接。我目前正在处理一个连接并尝试通过存储库调用将结果提供给 kendo 网格 以下是示例的模型,由 "NoteNoteTypeJoins"
加入 "Notes" 和 "NoteTypes"
public class Note
{
public int ID { get; set; }
[Display(Name = "Short Title")]
[Required]
public String Title { get; set; }
[Display(Name = "Note Content")]
public String NoteText { get; set; }
public int UserID { get; set; }
//some fields left out for brevity
public ICollection<NoteStaffJoin> NoteStaffJoins { get; set; }
public ICollection<NoteClientJoin> NoteClientJoins { get; set; }
public ICollection<NoteOrgJoin> NoteOrgJoins { get; set; }
public ICollection<NoteNoteTypeJoin> NoteNoteTypeJoins { get; set; }
}
public class NoteNoteTypeJoin
{
public int NoteNoteTypeJoinID { get; set; }
public int NoteID { get; set; }
public int NoteTypeID { get; set; }
public DateTime? Saved { get; set; }
public int? UserID { get; set; }
public Note Note { get; set; }
public NoteType NoteType { get; set; }
}
public class NoteType
{
public int ID { get; set; }
public string Type { get; set; }
public int? ParentID { get; set; }
public int? NoteTypeGroupID { get; set; }
public int? DisplayOrder { get; set; }
public int? UserID { get; set; }
public ICollection<NoteNoteTypeJoin> NoteNoteTypeJoins { get; set; }
}
public FliveRetryContext(DbContextOptions<FliveRetryContext> options)
: base(options)
{
public DbSet<FliveRetry.Models.Note> Note { get; set; }
public DbSet<FliveRetry.Models.NoteType> NoteType { get; set; }
public DbSet<FliveRetry.Models.NoteNoteTypeJoin> NoteNoteTypeJoin { get; set; }
}
据 ef core 所见,外键等都已正确定义
CREATE TABLE [dbo].[NoteNoteTypeJoin] (
[NoteNoteTypeJoinID] INT IDENTITY (1, 1) NOT NULL,
[NoteID] INT NOT NULL,
[NoteTypeID] INT NOT NULL,
[Saved] DATETIME2 (7) NULL,
[UserID] INT NULL,
CONSTRAINT [PK_NoteNoteTypeJoin] PRIMARY KEY CLUSTERED ([NoteNoteTypeJoinID] ASC),
CONSTRAINT [FK_NoteNoteTypeJoin_Note_NoteID] FOREIGN KEY ([NoteID]) REFERENCES [dbo].[Note] ([ID]) ON DELETE CASCADE,
CONSTRAINT [FK_NoteNoteTypeJoin_NoteType_NoteTypeID] FOREIGN KEY ([NoteTypeID]) REFERENCES [dbo].[NoteType] ([ID]) ON DELETE CASCADE
);
GO
CREATE NONCLUSTERED INDEX [IX_NoteNoteTypeJoin_NoteID]
ON [dbo].[NoteNoteTypeJoin]([NoteID] ASC);
GO
CREATE NONCLUSTERED INDEX [IX_NoteNoteTypeJoin_NoteTypeID]
ON [dbo].[NoteNoteTypeJoin]([NoteTypeID] ASC);
上周我已经尝试了网络上的所有示例,但无法正确使用。我最终使用连接 table 中的 ID 使其工作,不需要调用 NoteTypes table:
public async Task<List<Note>> GetAllNotesForNoteTypeIDAsync(int notetypeid)
{
var noteData = await context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteTypeID == notetypeid))
.ToListAsync();
return noteData;
}
我必须将此引用循环处理选项添加到 startup.cs 才能使包含工作,感谢 Telerik 提供的信息:
services.AddRazorPages().AddNewtonsoftJson
(options => {
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
这同样有效,只查询左手 table,即使包括其他人:
public async Task<List<Note>> GetAllNotesForUserAsync(int userId)
{
var noteData = await context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.UserID == userId)
.ToListAsync();
return noteData;
}
我想按 NoteType 文本而不是 ID 进行搜索,因为不同版本的 ID 可能不同。 这就是我目前所拥有的,但它使页面崩溃,就像许多其他变体一样:
public async Task<List<Note>> GetAllNotesForNoteTypeAsync(string notetype)
{
var noteData = await context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteType.Type.ToString() == notetype))
.ToListAsync();
return noteData;
}
此崩溃并显示以下消息:
An unhandled exception occurred while processing the request.
InvalidOperationException: The LINQ expression 'DbSet<NoteNoteTypeJoin>
.Where(n0 => EF.Property<Nullable<int>>((EntityShaperExpression:
EntityType: Note
ValueBufferExpression:
(ProjectionBindingExpression: EmptyProjectionMember)
IsNullable: False
), "ID") != null && EF.Property<Nullable<int>>((EntityShaperExpression:
EntityType: Note
ValueBufferExpression:
(ProjectionBindingExpression: EmptyProjectionMember)
IsNullable: False
), "ID") == EF.Property<Nullable<int>>(n0, "NoteID"))
.Join(
outer: DbSet<NoteType>,
inner: n0 => EF.Property<Nullable<int>>(n0, "NoteTypeID"),
outerKeySelector: n1 => EF.Property<Nullable<int>>(n1, "ID"),
innerKeySelector: (o, i) => new TransparentIdentifier<NoteNoteTypeJoin, NoteType>(
Outer = o,
Inner = i
))
.Any(n0 => n0.Inner.Type.ToString() == __notetype_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
我也没有对最后加入的智能感知访问权限,这阻止了我在论坛上使用很多建议,所以像 .Where(n => n.NoteNoteTypeJoins.Type == notetype)) 这样的东西'不可用,因为 .Type 在 NoteNoteTypeJoins 之后不可用。
这些是我需要过滤的四个多对多关系:
Note = await _context.Note
.Include(i => i.NoteOrgJoins).ThenInclude(i => i.Org)
.Include(i => i.NoteClientJoins).ThenInclude(i => i.Client)
.Include(i => i.NoteStaffJoins).ThenInclude(i => i.Staff)
.Include(i => i.NoteNoteTypeJoins).ThenInclude(i => i.NoteType)
如果有人可以建议一个有效的导航调用而不是加入,那至少可以让我摆脱笔记类型调用的麻烦,我会很兴奋,如果你能告诉我如何添加其他调用好吧,那会更好。我仍在学习 C# 和剃刀,所以它可能是调用本身之外的东西,但我试图坚持标准设置。
感谢大家
I also don't have intellisense access to the last join, which is stopping me using a lot of suggestions on forums so something like .Where(n => n.NoteNoteTypeJoins.Type == notetype)) isn't available because .Type isn't available after NoteNoteTypeJoins.
原因是 EF Core 3 中禁用了隐式客户端计算。
参考:
您可以像下面这样更改您的代码:
var noteData = await _context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.ToListAsync();
var d = noteData.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteType.Type.ToString() == notetype))
.ToList();
另一种方式是你的NoteType
class中的Type
属性是string.No的类型需要使用ToString()
方法:
var noteData = await _context.Note
.Include(n => n.NoteNoteTypeJoins)
.ThenInclude(t => t.NoteType)
.Where(i => i.NoteNoteTypeJoins.Any(x => x.NoteType.Type == notetype))
.ToListAsync();