我需要能够将Linq查询作为字符串存储在数据库中,然后加载它并在以后运行它。
我很难绕过如何做到这一点。
我发现这个库可以说它可以做到:https://github.com/esskar/Serialize.Linq
但是持有文档的博客已经关闭,我无法从示例中弄清楚,过多的事情正在发生。
任何人都可以向我展示或链接到一个简单的linq语句示例,该语句被序列化然后反序列化并运行吗?
答案 0 :(得分:1)
我不知道这是否是性能最佳选择(我不确定它的好坏),但这是实现所需功能的选项。
IQueryable ToString()方法允许您以编程方式检索IQueryable对象将生成并作为数据库查询运行的SQL。
然后,您可以在实体框架原始SQL查询中使用该SQL字符串。
以下示例将使用现成的Microsoft ASP.NET Identity DbContext。
IQueryable ToString()示例:
ApplicationDbContext db = new ApplicationDbContext();
IQueryable query = db.Users.Where(w => w.Email != null);
string generatedSql = query.ToString();
字符串generatedSql
将包含此内容:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Email] AS [Email],
[Extent1].[EmailConfirmed] AS [EmailConfirmed],
[Extent1].[PasswordHash] AS [PasswordHash],
[Extent1].[SecurityStamp] AS [SecurityStamp],
[Extent1].[PhoneNumber] AS [PhoneNumber],
[Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent1].[LockoutEnabled] AS [LockoutEnabled],
[Extent1].[AccessFailedCount] AS [AccessFailedCount],
[Extent1].[UserName] AS [UserName]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE [Extent1].[Email] IS NOT NULL
这是一个使用IQueryable对象上的Include()方法的示例,以显示它将生成哪种SQL:
ApplicationDbContext db = new ApplicationDbContext();
IQueryable query = db.Users
.Include(i => i.Claims)
.Include(i => i.Roles)
.Where(w => w.Email != null);
string generatedSql = query.ToString();
添加Include方法后,字符串generatedSql
将包含以下内容:
SELECT
[UnionAll1].[AccessFailedCount] AS [C1],
[UnionAll1].[Id] AS [C2],
[UnionAll1].[Email] AS [C3],
[UnionAll1].[EmailConfirmed] AS [C4],
[UnionAll1].[PasswordHash] AS [C5],
[UnionAll1].[SecurityStamp] AS [C6],
[UnionAll1].[PhoneNumber] AS [C7],
[UnionAll1].[PhoneNumberConfirmed] AS [C8],
[UnionAll1].[TwoFactorEnabled] AS [C9],
[UnionAll1].[LockoutEndDateUtc] AS [C10],
[UnionAll1].[LockoutEnabled] AS [C11],
[UnionAll1].[AccessFailedCount1] AS [C12],
[UnionAll1].[UserName] AS [C13],
[UnionAll1].[C1] AS [C14],
[UnionAll1].[Id1] AS [C15],
[UnionAll1].[UserId] AS [C16],
[UnionAll1].[ClaimType] AS [C17],
[UnionAll1].[ClaimValue] AS [C18],
[UnionAll1].[C2] AS [C19],
[UnionAll1].[C3] AS [C20],
[UnionAll1].[C4] AS [C21]
FROM (SELECT
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Extent1].[AccessFailedCount] AS [AccessFailedCount],
[Extent1].[Id] AS [Id],
[Extent1].[Email] AS [Email],
[Extent1].[EmailConfirmed] AS [EmailConfirmed],
[Extent1].[PasswordHash] AS [PasswordHash],
[Extent1].[SecurityStamp] AS [SecurityStamp],
[Extent1].[PhoneNumber] AS [PhoneNumber],
[Extent1].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent1].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent1].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent1].[LockoutEnabled] AS [LockoutEnabled],
[Extent1].[AccessFailedCount] AS [AccessFailedCount1],
[Extent1].[UserName] AS [UserName],
[Extent2].[Id] AS [Id1],
[Extent2].[UserId] AS [UserId],
[Extent2].[ClaimType] AS [ClaimType],
[Extent2].[ClaimValue] AS [ClaimValue],
CAST(NULL AS varchar(1)) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4]
FROM [dbo].[AspNetUsers] AS [Extent1]
LEFT OUTER JOIN [dbo].[AspNetUserClaims] AS [Extent2] ON [Extent1].[Id] = [Extent2].[UserId]
WHERE [Extent1].[Email] IS NOT NULL
UNION ALL
SELECT
2 AS [C1],
[Extent3].[AccessFailedCount] AS [AccessFailedCount],
[Extent3].[Id] AS [Id],
[Extent3].[Email] AS [Email],
[Extent3].[EmailConfirmed] AS [EmailConfirmed],
[Extent3].[PasswordHash] AS [PasswordHash],
[Extent3].[SecurityStamp] AS [SecurityStamp],
[Extent3].[PhoneNumber] AS [PhoneNumber],
[Extent3].[PhoneNumberConfirmed] AS [PhoneNumberConfirmed],
[Extent3].[TwoFactorEnabled] AS [TwoFactorEnabled],
[Extent3].[LockoutEndDateUtc] AS [LockoutEndDateUtc],
[Extent3].[LockoutEnabled] AS [LockoutEnabled],
[Extent3].[AccessFailedCount] AS [AccessFailedCount1],
[Extent3].[UserName] AS [UserName],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS varchar(1)) AS [C5],
[Extent4].[UserId] AS [UserId],
[Extent4].[RoleId] AS [RoleId],
[Extent4].[UserId] AS [UserId1]
FROM [dbo].[AspNetUsers] AS [Extent3]
INNER JOIN [dbo].[AspNetUserRoles] AS [Extent4] ON [Extent3].[Id] = [Extent4].[UserId]
WHERE [Extent3].[Email] IS NOT NULL) AS [UnionAll1]
ORDER BY [UnionAll1].[Id] ASC, [UnionAll1].[C1] ASC
然后您可以随意存储这些SQL查询,当您准备运行它们时,您可以使用实体框架Raw SQL查询。
像这样:
ApplicationDbContext db = new ApplicationDbContext();
var users = db.Users.SqlQuery("Your SQL here");
//or this if you need your DbSet to be dynamic
ApplicationDbContext db = new ApplicationDbContext();
var users = db.Set<User>.SqlQuery("Your SQL here");
//or this for commands
ApplicationDbContext db = new ApplicationDbContext();
db.Database.ExecuteSqlCommand("Your SQL command string here");