将 sql 转换为 LINQ C#
Posted
技术标签:
【中文标题】将 sql 转换为 LINQ C#【英文标题】:Converting sql to LINQ C# 【发布时间】:2020-04-24 05:53:45 【问题描述】:我正在使用 LLBLGEN Pro 运行时框架并获取表的实体。 是否可以将此查询转换为 LINQ 表达式?
SELECT s1.SETTING_NAME, s1.SETTING_VALUE, s1.ROW_LST_UPD_TS, s1.MACHINE_NAME, s1.ROW_LST_UPD_UID
FROM EVENT_MGT.CONFIGURATION_LOG s1
INNER JOIN (
SELECT SETTING_NAME, MAX(ROW_LST_UPD_TS) ROW_LST_UPD_TS
FROM EVENT_MGT.CONFIGURATION_LOG
WHERE APP_ID = 173
-- and ROW_LST_UPD_TS >= CURRENT_TIMESTAMP - 7
GROUP BY SETTING_NAME
) s2 ON s1.SETTING_NAME = s2.SETTING_NAME AND s1.ROW_LST_UPD_TS = s2.ROW_LST_UPD_TS
WHERE s1.APP_ID = 173;
到目前为止我尝试过这个:
var log1 = config_log.Where(app => app.AppId == 173)
.Select(s => new
s.SettingName,
s.SettingValue,
s.RowLstUpdTs,
s.MachineName,
s.RowLstUpdUid)
.ToList()
.GroupBy(x => x.SettingName);
但这远不是我需要的。
【问题讨论】:
创建视图、将其映射到实体并使用 LINQ 进行查询会更好。 【参考方案1】:试试这样的
class Program
static void Main(string[] args)
int CURRENT_TIMESTAMP = 123;
List<CONFIGURATION_LOG> logs = new List<CONFIGURATION_LOG>();
var results = logs.Where(x => (x.APP_ID == 173) && (x.ROW_LST_UPD_TS >= CURRENT_TIMESTAMP - 7))
.OrderByDescending(x => x.ROW_LST_UPD_TS)
.GroupBy(x => x.SETTING_NAME)
.Select(x => x.FirstOrDefault())
.Select(x => new
setting_name = x.SETTING_NAME,
setting_value = x.SETTING_VALUE,
row_lst_upd_ts = x.ROW_LST_UPD_TS,
machine_name = x.MACHINE_NAME,
row_lst_upd_uid = x.ROW_LST_UPD_UID
).ToList();
public class EVENT_MGT
CONFIGURATION_LOG CONFIGURATION_LOG get; set;
public class CONFIGURATION_LOG
public string SETTING_NAME get; set;
public string SETTING_VALUE get; set;
public int ROW_LST_UPD_TS get; set;
public string MACHINE_NAME get; set;
public string ROW_LST_UPD_UID get; set;
public int APP_ID get; set;
【讨论】:
抛出异常“对'Join'的方法调用没有已知的映射数据库函数或其他已知处理程序。” 类型:SD.LLBLGen.Pro.ORMSupportClasses.ORMQueryConstructionException 多亏了 jdweng,我终于找到了我想要的东西:【参考方案2】:您提供损失信息。也许你想要一个像这个键的东西:Entity Framework
。关注这个link;
此外,我有一个想法,优化使用调用 SQL 查询命令从表中获取数据,包括使用 C# 不使用实体框架的 image
数据类型的列,分 3 个步骤,并附有一个小示例:
步骤 0:(默认)创建一个新表。这是我的桌子TBUsers
:
CREATE TABLE [dbo].[TBUsers]
(
[STT] [BIGINT] IDENTITY(1,1) NOT NULL,
[HoTen] [NVARCHAR](MAX) NOT NULL,
[MaSo] [NVARCHAR](50) NOT NULL,
[MatKhau] [NVARCHAR](MAX) NOT NULL,
[KhoaLop] [NVARCHAR](MAX) NOT NULL,
[MaTheGui] [NVARCHAR](50) NOT NULL,
[PhanQuyen] [INT] NOT NULL,
[ChoPhepHoatDong] [BIT] NOT NULL,
[NguoiThem] [NVARCHAR](MAX) NOT NULL,
[NgayThem] [DATETIME] NOT NULL,
[SoDuKhaDung] [BIGINT] NOT NULL,
[DangGui] [BIT] NOT NULL,
[TruyCapLanCuoi] [DATETIME] NULL,
[ThoiGianGuiCuoi] [DATETIME] NULL,
[HinhAnh] [IMAGE] NULL,
[DonGia] [BIGINT] NULL,
CONSTRAINT [PK_TBUsers]
PRIMARY KEY CLUSTERED ([MaTheGui] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
第一步:新建一个对应上表的类,并创建2个构造函数Users
:
public class Users
public Users()
public Users(object sTT, object hoTen, object maSo, object matKhau, object khoaLop, object maTheGui, object phanQuyen, object choPhepHoatDong,
object nguoiThem, object ngayThem, object soDuKhaDung, object dangGui, object truyCapLanCuoi, object thoiGianGuiCuoi, object hinhAnh,object donGia)
STT = sTT.ToString();
HoTen = hoTen.ToString();
MaSo = maSo.ToString();
MatKhau = matKhau.ToString();
KhoaLop = khoaLop.ToString();
MaTheGui = maTheGui.ToString();
PhanQuyen = phanQuyen.ToString();
ChoPhepHoatDong = choPhepHoatDong.ToString();
NguoiThem = nguoiThem.ToString();
NgayThem = ngayThem.ToString();
SoDuKhaDung = soDuKhaDung.ToString();
DangGui = dangGui.ToString();
TruyCapLanCuoi = truyCapLanCuoi.ToString();
ThoiGianGuiCuoi = thoiGianGuiCuoi.ToString();
HinhAnh = hinhAnh==System.DBNull.Value?null: (byte[])hinhAnh;
DonGia = donGia.ToString();
Color = (bool)choPhepHoatDong;
public string STT get; set;
public string HoTen get; set;
public string MaSo get; set;
public string MatKhau get; set;
public string KhoaLop get; set;
public string MaTheGui get; set;
public string PhanQuyen get; set;
public string ChoPhepHoatDong get; set;
public string NguoiThem get; set;
public string NgayThem get; set;
public string SoDuKhaDung get; set;
public string DangGui get; set;
public string TruyCapLanCuoi get; set;
public string ThoiGianGuiCuoi get; set;
public byte[] HinhAnh get; set;
public string DonGia get; set;
public bool Color get; set;
第 2 步:使用 ParseUser
函数从数据库中获取 Users
:
public static Users ParseUser(DataRow row)
var stt = row["STT"];
var hoTen = row["HoTen"];
var maSo = row["MaSo"];
var matKhau = row["MatKhau"];
var khoaLop = row["KhoaLop"];
var maTheGui = row["MaTheGui"];
var phanQuyen = row["PhanQuyen"];
var choPhepHoatDong = row["ChoPhepHoatDong"];
var nguoiThem = row["ChoPhepHoatDong"];
var ngayThem = row["ChoPhepHoatDong"];
var soDuKhaDung = row["SoDuKhaDung"];
var dangGui = row["DangGui"];
var truyCapLanCuoi = row["TruyCapLanCuoi"];
var guiLanCuoi = row["ThoiGianGuiCuoi"];
var hinhAnh = row["HinhAnh"] == System.DBNull.Value ? null : row["HinhAnh"];
var donGia = row["DonGia"];
return new Users(stt, hoTen, maSo, matKhau, khoaLop, maTheGui, phanQuyen, choPhepHoatDong, nguoiThem, ngayThem, soDuKhaDung, dangGui,
truyCapLanCuoi, guiLanCuoi, hinhAnh, donGia);
第 3 步: 使用 ParseUser
函数轻松获取 Users 类的实例:
Users user = ParseUser(sqlUtility.GetDataTable($"SELECT * FROM [dbo].[TBUsers] WHERE MaSo = 'xxx' AND ChoPhepHoatDong=1;").Rows[0]);
同样,您可以创建一个类来使用任何集合(例如List<User>
或IEnumerable<User>
)检索整个Users
。您可以使用 LinQ 来查询这些数据。
【讨论】:
我想知道这是如何回答这个问题的。您能否再次检查您是否回答了正确的问题? 这是我做的项目中的代码。我分享解决问题的解决方案,可能OP可以做这样的事情。 除了您没有显示原始帖子中的任何程序元素这一事实(如果不这样做有什么帮助?),问题是将查询转换为 LINQ,但您只需说“您可以使用LinQ 查询此数据”,这不是该问题的答案。此外,该问题已标记为 Oracle,但您使用的是 T-SQL 语法。 我只是用自己的眼光分享了解决问题的方向,希望对他有所帮助。很抱歉给您带来不便。【参考方案3】:感谢 jdweng,我想出了如何得到我需要的东西:
var results = config_log.Where(x => x.AppId == 173)
.OrderByDescending(x => x.RowLstUpdTs).ToList()
.GroupBy(x => x.SettingName )
.Select(x => new
setting_name = x.Select(y => y.SettingName).FirstOrDefault(),
setting_value = x.Select(y => y.SettingValue).FirstOrDefault(),
row_lst_upd_ts = x.Select(y => y.RowLstUpdTs).FirstOrDefault(),
machine_name = x.Select(y => y.MachineName).FirstOrDefault(),
row_lst_upd_uid = x.Select(y => y.RowLstUpdUid).FirstOrDefault()
).ToList();
【讨论】:
以上是关于将 sql 转换为 LINQ C#的主要内容,如果未能解决你的问题,请参考以下文章
将 T-SQL string_agg 转换为 LINQ C#
将 Oracle SQL 转换为 LLBLGEN LINQ 表达式 C#