SQL_LINQ left join list<string>

本文介绍如何利用LINQ技术,在数据库表与字符串列表之间进行匹配操作,包括从数据库表中筛选出与列表中元素匹配的记录,并处理不存在于数据库中的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们经常会有这样ongcha的需求:给一个字符串的列表,到数据库中查找相关匹配的字段,当然在数据库中不存在的最后也要返回相应的结果。既有数据库表又有List<string>列表,这样使用linq应该如何做到。

直接上代码:

<span style="font-size:14px;">var filtered = from c in db.Ctable
          <span style="color:#ff0000;"> where tntable.Contains(c.CarID)</span>
           select new 
           {
              CarID = c.CarID,
              Name =  c.OwnerName,
              Hours = c.Hours
           };

var line = <span style="color:#ff0000;">from x in tntable</span>
           join i in filtered.ToList() on x equals u.CarID into i_match
           from i in i_match.DefaultIfEmpty()
           select { x, i };</span>

其中的
<span style="font-size:18px;">tntable 是一个list<string> 列表 </span>
using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data; using System.Data.SqlClient; using System.Configuration; using System.Web.Services; using System.Web.Script.Services; namespace WebApplication1 { public partial class WebForm2 : System.Web.UI.Page { private readonly List<Product> _products = new List<Product> { new Product { Id = 1, Name = "专业减震跑步鞋", Category = "运动鞋", Price = 599, ImageUrl = "image/专业减震跑步鞋.jpg", Brand = "耐克", Description = "专业级减震科技,适合长距离跑步" }, new Product { Id = 2, Name = "专业篮球鞋", Category = "运动鞋", Price = 699, ImageUrl = "image/专业篮球鞋.jpg", Brand = "阿迪达斯", Description = "高帮支撑设计,保护脚踝" }, new Product { Id = 3, Name = "多功能运动背包", Category = "运动装备", Price = 299, ImageUrl = "image/多功能运动背包.jpg", Brand = "彪马" }, new Product { Id = 4, Name = "专业运动智能手表", Category = "运动配件", Price = 799, ImageUrl = "image/专业运动智能手表.jpg", Brand = "Apple" }, new Product { Id = 5, Name = "速干透气运动T恤", Category = "运动服饰", Price = 199, ImageUrl = "image/速干透气运动T恤.jpg", Brand = "耐克" }, new Product { Id = 6, Name = "弹性运动短裤", Category = "运动服饰", Price = 159, ImageUrl = "image/弹性运动短裤.jpg", Brand = "阿迪达斯" } }; // 用户实体类 public class User { } // 商品实体类 public class Product { public int Id { get; set; } public string Name { get; set; } public string Category { get; set; } public decimal Price { get; set; } public string ImageUrl { get; set; } public string Description { get; set; } public string Brand { get; set; } } public class CartItem { public int ProductId { get; set; } public string ProductName { get; set; } public decimal Price { get; set; } public int Quantity { get; set; } public string ImageUrl { get; set; } } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 记录用户浏览记录(示例) if (Session["UserID"] != null) { int userId = Convert.ToInt32(Session["UserID"]); LogUserBrowse(userId, 1); // 假设浏览了商品ID=1 } } } private List<Product> GetRecommendedProducts() { List<Product> products = new List<Product>(); if (Session["UserID"] == null) return products; int userId = Convert.ToInt32(Session["UserID"]); string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString; // 读取配置 using (SqlConnection conn = new SqlConnection(connStr)) { conn.Open(); string sql = @"SELECT p.*, c.CategoryName, b.BrandName FROM tb_Product p JOIN tb_Category c ON p.CategoryID = c.CategoryID JOIN tb_Brand b ON p.BrandID = b.BrandID WHERE p.CategoryID IN ( SELECT DISTINCT CategoryID FROM tb_Product WHERE ProductID IN ( SELECT ProductID FROM tb_UserBrowse WHERE UserID=@UserID ) ) OR p.BrandID IN ( SELECT DISTINCT BrandID FROM tb_Product WHERE ProductID IN ( SELECT ProductID FROM tb_UserBrowse WHERE UserID=@UserID ) )"; using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@UserID", userId); using (SqlDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { // 填充 Product 对象... } } } } return products; } private void LogUserBrowse(int userId, int productId) { } } } 根据已有的前后端代码更新改善后端代码,给出完整的后端代码
06-11
using System; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Web; using System.Web.UI; using System.Web.Configuration; namespace WebApplication1 { public partial class WebForm3 : System.Web.UI.Page { private int currentProductId; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { if (!ValidateRequestParameters()) { Response.Redirect("~/Default.aspx"); return; } LoadProductDetails(currentProductId); LoadRelatedProducts(currentProductId); LogPageVisit(currentProductId); } } /// <summary> /// 验证请求参数并获取商品ID /// </summary> private bool ValidateRequestParameters() { if (!int.TryParse(Request.QueryString["id"], out currentProductId)) { ShowErrorMessage("无效的商品ID参数"); return false; } if (currentProductId <= 0) { ShowErrorMessage("商品ID必须为正整数"); return false; } return true; } /// <summary> /// 加载商品详情 /// </summary> private void LoadProductDetails(int productId) { string connString = GetConnectionString(); if (string.IsNullOrEmpty(connString)) { ShowErrorMessage("数据库连接配置错误"); return; } try { using (var conn = new SqlConnection(connString)) { // 获取商品基本信息和图片 string query = @" SELECT p.ProductID, p.ProductName, p.Subtitle, p.Description, p.Price, p.DiscountPrice, p.StockQuantity, p.CategoryID, p.Rating, p.ReviewCount, c.CategoryName, pi.ImagePath, STRING_AGG(pv.VariantName, ', ') AS AvailableVariants FROM Products p INNER JOIN Categories c ON p.CategoryID = c.CategoryID LEFT JOIN ProductImages pi ON p.ProductID = pi.ProductID AND pi.IsDefault = 1 LEFT JOIN ProductVariants pv ON p.ProductID = pv.ProductID WHERE p.ProductID = @ProductID GROUP BY p.ProductID, p.ProductName, p.Subtitle, p.Description, p.Price, p.DiscountPrice, p.StockQuantity, p.CategoryID, p.Rating, p.ReviewCount, c.CategoryName, pi.ImagePath"; using (var cmd = new SqlCommand(query, conn)) { cmd.Parameters.AddWithValue("@ProductID", productId); conn.Open(); using (SqlDataReader reader = cmd.ExecuteReader()) { if (reader.Read()) { DisplayProductDetails(reader); productContainer.Visible = true; } else { ShowErrorMessage("找不到指定的商品"); } } } } } catch (SqlException sqlEx) { LogError($"SQL错误: {sqlEx.Message}", sqlEx); ShowErrorMessage("数据库连接错误,请稍后再试"); } catch (Exception ex) { LogError($"加载商品信息失败: {ex.Message}", ex); ShowErrorMessage("加载商品信息时出错"); } } /// <summary> /// 显示商品详情到页面控件 /// </summary> private void DisplayProductDetails(SqlDataReader reader) { // 基本信息 ltProductName.Text = HttpUtility.HtmlEncode(reader["ProductName"].ToString()); ltSubtitle.Text = HttpUtility.HtmlEncode(reader["Subtitle"].ToString()); ltCategory.Text = HttpUtility.HtmlEncode(reader["CategoryName"].ToString()); // 价格 decimal price = Convert.ToDecimal(reader["Price"]); ltPrice.Text = price.ToString("C"); if (!Convert.IsDBNull(reader["DiscountPrice"]) && price > Convert.ToDecimal(reader["DiscountPrice"])) { ltDiscountPrice.Text = Convert.ToDecimal(reader["DiscountPrice"]).ToString("C"); } // 库存 int stock = Convert.ToInt32(reader["StockQuantity"]); ltStock.Text = stock.ToString(); ltStockStatus.Text = stock > 0 ? "<span class='text-success'><i class='bi bi-check-circle'></i>有货</span>" : "<span class='text-danger'><i class='bi bi-x-circle'></i>缺货</span>"; // 评分 decimal rating = Convert.ToDecimal(reader["Rating"]); ltRating.Text = GenerateRatingStars(rating); ltReviewCount.Text = reader["ReviewCount"].ToString(); // 图片 string imagePath = reader["ImagePath"]?.ToString() ?? ""; imgProduct.ImageUrl = !string.IsNullOrEmpty(imagePath) ? imagePath : "~/Images/default-product.jpg"; // 描述 ltDescription.Text = HttpUtility.HtmlEncode(reader["Description"].ToString()); // 商品型号 if (!reader.IsDBNull(reader.GetOrdinal("AvailableVariants"))) { ltAvailableVariants.Text = reader["AvailableVariants"].ToString(); } } /// <summary> /// 生成评分星星HTML /// </summary> private string GenerateRatingStars(decimal rating) { int fullStars = (int)rating; bool hasHalfStar = (rating - fullStars) >= 0.5M; int emptyStars = 5 - fullStars - (hasHalfStar ? 1 : 0); return $@" {string.Concat(Enumerable.Repeat("<i class='bi bi-star-fill text-warning'></i>", fullStars))} {(hasHalfStar ? "<i class='bi bi-star-half text-warning'></i>" : "")} {string.Concat(Enumerable.Repeat("<i class='bi bi-star text-warning'></i>", emptyStars))} <span class='ms-2'>{rating:F1}</span>"; } /// <summary> /// 加载相关商品 /// </summary> private void LoadRelatedProducts(int productId) { string connString = GetConnectionString(); if (string.IsNullOrEmpty(connString)) return; try { using (var conn = new SqlConnection(connString)) { // 获取同类别的前4个相关商品 string query = @" SELECT TOP 4 p.ProductID, p.ProductName, p.Price, pi.ImagePath FROM Products p INNER JOIN Categories c ON p.CategoryID = c.CategoryID CROSS APPLY ( SELECT TOP 1 ImagePath FROM ProductImages WHERE ProductID = p.ProductID ORDER BY IsDefault DESC ) pi WHERE p.CategoryID = ( SELECT CategoryID FROM Products WHERE ProductID = @ProductID ) AND p.ProductID <> @ProductID ORDER BY NEWID()"; using (var cmd = new SqlCommand(query, conn)) { cmd.Parameters.AddWithValue("@ProductID", productId); conn.Open(); rptRelatedProducts.DataSource = cmd.ExecuteReader(); rptRelatedProducts.DataBind(); } } } catch (Exception ex) { LogError($"加载相关商品失败: {ex.Message}", ex); } } /// <summary> /// 添加到购物车按钮点击事件 /// </summary> protected void btnAddToCart_Click(object sender, EventArgs e) { if (!ValidateRequestParameters()) return; try { // 获取用户选择的型号 string variant = Request.Form["product_variant"]; // 获取数量 int quantity; if (!int.TryParse(txtQuantity.Value, out quantity) || quantity < 1) { quantity = 1; } // 添加到购物车 Cart cart = GetOrCreateCart(); cart.AddItem(currentProductId, quantity, variant); // 更新购物车数量显示 UpdateCartBadge(cart.TotalItems); // 显示成功消息 ClientScript.RegisterStartupScript(GetType(), "AddToCartSuccess", "showToast('success', '商品已添加到购物车!');", true); } catch (Exception ex) { LogError($"添加到购物车失败: {ex.Message}", ex); ClientScript.RegisterStartupScript(GetType(), "AddToCartError", "showToast('error', '添加到购物车失败,请重试');", true); } } /// <summary> /// 记录页面访问 /// </summary> private void LogPageVisit(int productId) { try { string connString = GetConnectionString(); using (var conn = new SqlConnection(connString)) { string query = @" INSERT INTO ProductVisits (ProductID, UserIP, VisitDate) VALUES (@ProductID, @UserIP, GETDATE())"; using (var cmd = new SqlCommand(query, conn)) { cmd.Parameters.AddWithValue("@ProductID", productId); cmd.Parameters.AddWithValue("@UserIP", GetUserIP()); conn.Open(); cmd.ExecuteNonQuery(); } } } catch { // 访问日志记录失败不影响主流程 } } /// <summary> /// 获取或创建用户购物车 /// </summary> private Cart GetOrCreateCart() { Cart cart = Session["ShoppingCart"] as Cart; if (cart == null) { cart = new Cart(); Session["ShoppingCart"] = cart; } return cart; } /// <summary> /// 更新页面购物车徽章显示 /// </summary> private void UpdateCartBadge(int count) { // 查找母版页中的购物车徽章 var cartBadge = Master?.FindControl("cartBadge") as System.Web.UI.HtmlControls.HtmlGenericControl; if (cartBadge != null) { cartBadge.InnerText = count.ToString(); cartBadge.Visible = count > 0; } } /// <summary> /// 获取数据库连接字符串 /// </summary> private string GetConnectionString() { return WebConfigurationManager.ConnectionStrings["DB-NetShopsConnectionString"]?.ConnectionString; } /// <summary> /// 获取用户IP地址 /// </summary> private string GetUserIP() { string ip = Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (string.IsNullOrEmpty(ip)) { ip = Request.ServerVariables["REMOTE_ADDR"]; } else { string[] addresses = ip.Split(','); if (addresses.Length != 0) { return addresses[0]; } } return ip; } /// <summary> /// 显示错误消息 /// </summary> private void ShowErrorMessage(string message) { if (ltErrorMessage != null) { ltErrorMessage.Text = $"<div class='alert alert-danger'>{HttpUtility.HtmlEncode(message)}</div>"; ltErrorMessage.Visible = true; productContainer.Visible = false; } } /// <summary> /// 记录错误日志 /// </summary> private void LogError(string message, Exception ex) { // 实际项目中应使用日志框架(如log4net/NLog) System.Diagnostics.Debug.WriteLine($"{message}\n{ex}"); // 也可以保存到数据库或文件 try { string logMessage = $"[{DateTime.Now}] {message}\nException: {ex}\n\n"; System.IO.File.AppendAllText(Server.MapPath("~/App_Data/error.log"), logMessage); } catch { // 文件记录失败时不中断 } } } /// <summary> /// 购物车项 /// </summary> public class CartItem { public int ProductId { get; set; } public int Quantity { get; set; } public string Variant { get; set; } public DateTime AddedTime { get; set; } = DateTime.Now; } /// <summary> /// 购物车类 /// </summary> public class Cart { public List<CartItem> Items { get; } = new List<CartItem>(); public int TotalItems => Items.Sum(item => item.Quantity); public decimal TotalPrice { get { // 实际项目中应从数据库获取当前价格 return 0; // 简化为0 } } /// <summary> /// 添加商品到购物车 /// </summary> public void AddItem(int productId, int quantity, string variant = "") { var existingItem = Items.FirstOrDefault(i => i.ProductId == productId && i.Variant == variant); if (existingItem != null) { existingItem.Quantity += quantity; } else { Items.Add(new CartItem { ProductId = productId, Quantity = quantity, Variant = variant }); } } /// <summary> /// 从购物车移除商品 /// </summary> public void RemoveItem(int productId, string variant = "") { var itemToRemove = Items.FirstOrDefault(i => i.ProductId == productId && i.Variant == variant); if (itemToRemove != null) { Items.Remove(itemToRemove); } } /// <summary> /// 清空购物车 /// </summary> public void Clear() { Items.Clear(); } } } 根据后端代码更新数据库代码,使网页能够正常运行
最新发布
06-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值