协助将 SQL 查询转换为 LINQ 查询
Posted
技术标签:
【中文标题】协助将 SQL 查询转换为 LINQ 查询【英文标题】:Assistance converting SQL query to a LINQ query 【发布时间】:2021-09-24 04:31:51 【问题描述】:他们告诉我用 LINQ 编写我用 SQL 查询编写的代码。但我做不到。有知道的可以帮帮我吗?
我的 SQL 代码:
DropDownListInvoiceTown.Items.Clear();
Session["ilID"] = Convert.ToInt32(DropDownListInvoiceCity.SelectedValue);
SqlConnection cnn = new SqlConnection(@"Data Source = ENKITEST; Initial Catalog = FAZIKI; User ID = WebAdmin; Password = !ConAdmin");
SqlCommand kmt = new SqlCommand();
kmt.Connection = cnn;
kmt.CommandText = "SELECT wt.IDTown as IlceID, wt.TownName as IlceAdi FROM ArkadasWebSite.dbo.WebArkadasCities as wc JOIN ArkadasWebSite.dbo.WebArkadasTowns as wt on wc.IDCity = wt.IDTown WHERE wc.IDCity=@DropDownListInvoiceCity ORDER BY wc.CityName";
kmt.Parameters.AddWithValue("@DropDownListInvoiceCity", DropDownListInvoiceCity.SelectedValue);
SqlDataReader oku;
cnn.Open();
oku = kmt.ExecuteReader();
DropDownListInvoiceTown.DataSource = oku;
DropDownListInvoiceTown.DataValueField = "IlceID";
DropDownListInvoiceTown.DataTextField = "IlceAdi";
DropDownListInvoiceTown.DataBind();
cnn.Close();
如果我修复的代码是:
DropDownListInvoiceTown.Items.Clear();
Session["ilID"] = Convert.ToInt32(DropDownListInvoiceCity.SelectedValue);
DropDownListInvoiceTown.DataSource = arkadas.WebArkadasCities.Where(x => x.IDCity == arkadas.WebArkadasTowns.Where(w => w.IDTown == DropDownListInvoiceCity.SelectedValue).Select(w => w.TownName).FirstOrDefault()).Select(x => x.CityName).ToList();
DropDownListInvoiceTown.DataValueField = "IlceID";
DropDownListInvoiceTown.DataTextField = "IlceAdi";
DropDownListInvoiceTown.DataBind();
但它不起作用,所以它返回空。我该怎么做?
【问题讨论】:
一个好的开始是找到一个支持 LINQ 的 O/R 映射器。 @GertArnold OP 已经在使用 LINQ 映射器,这实际上是他们的全部重点,他们需要帮助将他们之前的 SQL 尝试转换为 LINQ @ChrisSchaller 我没有看到对“LINQ 映射器”的任何引用。是的,arkadas.WebArkadasCities
,但它是什么? 确切地知道使用了哪个 ORM 以及类模型是什么样的,这总是至关重要的。像往常一样,人们开始发布包括连接在内的 LINQ 语句,但如果导航属性到位,这些手动连接几乎没有必要。
@GertArnold 实际上是irrelevant使用的是哪个ORM,这个问题是一个简单的将SQL转换为LINQ表达式的请求。是的,连接可能不是必需的,这取决于模型,但如果您愿意,使用它们仍然有效。这里有足够的高质量答案。
@burak 您能否更新您的帖子以包含 WebArkadasCities
和 WebArkadasTowns
类的定义,以获得可靠的答案,您可以使用该答案而无需我们做出假设。
【参考方案1】:
最终我们希望将 SQL 表达式转换为 LINQ 表达式。此答案假定您使用的是 ORM 或至少 LINQ to SQL,并且原始 SQL 是返回预期记录集的正确语句。
如果原始 SQL 不正确,则此 LINQ 解决方案将无济于事,而是有关如何将 SQL 转换为 LINQ 的一般指导。鉴于此 SQL:
SELECT wt.IDTown as IlceID, wt.TownName as IlceAdi
FROM ArkadasWebSite.dbo.WebArkadasCities as wc
JOIN ArkadasWebSite.dbo.WebArkadasTowns as wt on wc.IDCity = wt.IDTown
WHERE wc.IDCity=@DropDownListInvoiceCity
ORDER BY wc.CityName
他们告诉我用 LINQ 编写我用 SQL 查询编写的代码
Linq 有一个可以使用的查询表示法,它与 SQL 非常相似,可以看到下面是对原始查询的直接转换,主要需要注意的是子句的顺序不同以及语法稍微调换了一下,但是对于精通 SQL 的人来说还是很容易辨认的。
var linqQuery = from wc in arkadas.WebArkadasCities
where wc.IDCity == DropDownListInvoiceCity.SelectedValue
join wt in arkadas.WebArkadasTowns on wc.IDCity equals wt.IDTown
order by wc.CityName
select new
IlceID = wt.IDTown,
IlceAdi = wt.TownName
;
可以使用 linq fluent 表示法编写相同的查询:
var linqQuery = arkadas.WebArkadasCities.Where(wc => wc.IDCity == DropDownListInvoiceCity.SelectedValue)
.Join(arkadas.WebArkadasTowns, wc => wc.IDCity, wt => wt.IDTown, (wc, wt) => new
wt.IDTown,
wt.TownName,
wc.CityName
)
.OrderBy(x => x.CityName)
.Select(x => new
IlceID = x.IDTown,
IlceAdi = x.TownName
);
然后你可以使用这个linqQuery
参考,但是你选择在你的原始代码中定义它:
DropDownListInvoiceTown.Items.Clear();
Session["ilID"] = Convert.ToInt32(DropDownListInvoiceCity.SelectedValue);
DropDownListInvoiceTown.DataSource = linqQuery.ToList();
DropDownListInvoiceTown.DataValueField = "IlceID";
DropDownListInvoiceTown.DataTextField = "IlceAdi";
DropDownListInvoiceTown.DataBind();
如果您使用的是 ORM,并且在 WebArkadasCities
和 WebArkadasTowns
之间定义了导航属性,则可以通过省略连接大大简化 linq 查询。
以下查询假设您的模型可能不存在,在这种情况下,我们假设
WebArkadasTowns
有一个名为City
的导航属性,它将城镇 链接到城市 他们属于。在此示例中,假设每个 city 有多个 towns。这个假设是基于一个城镇小于一个城市的普遍预期,它与我的当地环境相匹配,其中 town 被称为 suburb 和一个城市是直辖市(或省)
在这种情况下,我们还将转置查询以从
WebArkadasTowns
中进行选择,因为这样可以使查询更清晰。由于导航属性,我保留了自动为我们定义的原始查询的工件。
查询符号:
var linqQuery = //from wc in arkadas.WebArkadasCities
from wt in arkadas.WebArkadasTowns// on wc.IDCity equals wt.IDTown
where wt.City.IDCity == DropDownListInvoiceCity.SelectedValue
order by wt.City.CityName
select new
IlceID = wt.IDTown,
IlceAdi = wt.TownName
;
流利的符号:
var linqQuery = arkadas.WebArkadasTowns.Where(wt => wt.City.IDCity == DropDownListInvoiceCity.SelectedValue)
.OrderBy(wt => wt.City.CityName)
.Select(wt => new
IlceID = wt.IDTown,
IlceAdi = wt.TownName
);
【讨论】:
这正是我正在寻找的答案,既具有描述性又具有指导意义。非常感谢先生,您所说的非常易于理解和具有启发性。多亏了你,我或多或少地了解了 linq 查询。我不能感谢你。再次感谢。 @ChrisSchaller 如果您下次提供更多详细信息,则可以更轻松地发布详细答案;)我不喜欢 猜测 涉及数据模型的地方,但有时您只需要冒着风险。祝您在 linq 之旅中一切顺利。我给你留下这句话:“每个 SQL 结果集都可以通过 Linq 生成,但这并不意味着你应该这样做,或者它会生成高效的 SQL”。总有办法,但有时 LINQ 和 SQL 之间的折衷可以产生最好的结果。【参考方案2】:试试下面的查询
arkadas.WebArkadasCities
.Join(arkadas.WebArkadasTowns, wc=> wc.IDCity, wt=> wt.IDTown, (wc, wt) => new wc, wt)
.where(x=> x.wt.IDCity==DropDownListInvoiceCity.SelectedValue)
.Select(s=> new
IlceID=s.wt.IDTown,
IlceAdi=s.wt.TownName
).OrderBy(o => o.IlceID).ToList();
【讨论】:
首先,非常感谢您的努力。先生,我试过你写的代码,但无法根据省名加载区名。 @NagibMahfuz以上是关于协助将 SQL 查询转换为 LINQ 查询的主要内容,如果未能解决你的问题,请参考以下文章