协助将 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 您能否更新您的帖子以包含 WebArkadasCitiesWebArkadasTowns 类的定义,以获得可靠的答案,您可以使用该答案而无需我们做出假设。 【参考方案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,并且在 WebArkadasCitiesWebArkadasTowns 之间定义了导航属性,则可以通过省略连接大大简化 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 查询的主要内容,如果未能解决你的问题,请参考以下文章

将 SQL 转换为 Linq 查询

如何将 linq 查询转换为 SQL 查询?

将 SQL 子查询转换为 Linq 查询

如何将sql查询转换为linq查询

将 SQL 原始查询转换为 Linq

将 SQL 转换为 LINQ 查询