修正多處 LINQ-to-Entities 查詢,避免 Nullable .Contains()、.ToString()、Request[] 直接使用造成翻譯失敗。

API 查詢同步改寫 .Contains()、.OrderBy()、複雜 GroupBy/Math.Round,必要時 materialize 或加 HasValue。
Participation rate / kind breakdown 改在記憶體計算,同時檢查整數陣列 .Contains() 的型別安全性。
This commit is contained in:
2025-11-14 23:40:55 +08:00
parent 4fcbfb3801
commit 27f916eb9c
14 changed files with 245 additions and 115 deletions

View File

@@ -208,10 +208,12 @@ public class accountingController : BaseApiController
}
else if (sortBy.Equals("total"))
{
// ❌ 錯誤寫法: qry.OrderByDescending(o => o.price??0+o.tax??0)
// 運算符優先級問題,應該加括號確保正確運算
if (sortDesc)
qry = qry.OrderByDescending(o => o.price??0+o.tax??0);
qry = qry.OrderByDescending(o => (o.price ?? 0) + (o.tax ?? 0));
else
qry = qry.OrderBy(o => o.price ?? 0 + o.tax ?? 0);
qry = qry.OrderBy(o => (o.price ?? 0) + (o.tax ?? 0));
}
else
qry = qry.OrderByDescending(o => o.num);

View File

@@ -319,7 +319,9 @@ public class activityController : ApiController
{
//var stockDt = _db.stocks.AsEnumerable(); ;//庫存
var fileDt = _db.files.Where(f => f.subject.Contains(q.fileTxt)).Select(f => f.num.ToString());//文件
// ❌ 錯誤寫法: var fileDt = _db.files.Where(f => f.subject.Contains(q.fileTxt)).Select(f => f.num.ToString());
// 改為整數陣列,避免後續查詢中使用 .ToString()
var fileDt = _db.files.Where(f => f.subject.Contains(q.fileTxt)).Select(f => f.num).ToArray();//文件
//每個品項在每個倉庫的結餘量
var stockDt = (
@@ -368,13 +370,22 @@ public class activityController : ApiController
if (q.category.HasValue && q.category.Value > 0)
qry = qry.Where(o => o.category == q.category.Value);
if (!string.IsNullOrEmpty(q.categorys))
qry = qry.Where(o => q.categorys.Contains(o.category.HasValue ? o.category.Value.ToString() : "0"));
{
// ❌ 錯誤寫法: qry = qry.Where(o => q.categorys.Contains(o.category.HasValue ? o.category.Value.ToString() : "0"));
// LINQ to Entities 無法轉換資料庫欄位的 .ToString(),改為整數陣列比較
var categoryArray = q.categorys.Split(',').Select(x => int.TryParse(x, out int result) ? result : 0).ToArray();
qry = qry.Where(o => categoryArray.Contains(o.category ?? 0));
}
if (!string.IsNullOrEmpty(q.status))
qry = qry.Where(o => o.status.Contains(q.status));
if (!string.IsNullOrEmpty(q.extend))
qry = qry.Where(o => o.extend == q.extend);
if (!string.IsNullOrEmpty(q.fileTxt))
qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && fileDt.ToArray().Contains(f2.files_num.ToString())).Count() > 0);
{
// ❌ 錯誤寫法: qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && fileDt.ToArray().Contains(f2.files_num.ToString())).Count() > 0);
// fileDt 已改為整數陣列,直接比較即可
qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && fileDt.Contains(f2.files_num)).Count() > 0);
}
//qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && f2.files_num.ToString().Contains( String.Join(",", fileDt.Select(p => p.ToString()).ToArray()) )).Count() >0 ) ;
if (sortBy.Equals("subject"))
@@ -581,7 +592,10 @@ public class activityController : ApiController
qry = qry.Where(o => o.actItem_kind.kind.Contains(q.kindTxt));
if (!string.IsNullOrEmpty(q.is_reconcile))
qry = qry.Where(o => o.is_reconcile == q.is_reconcile);
qry = qry.Where(o => "1,2,4".Contains(o.category.HasValue ? o.category.Value.ToString() : "0")); //報名,掛單,贊助
// ❌ 錯誤寫法: qry = qry.Where(o => "1,2,4".Contains(o.category.HasValue ? o.category.Value.ToString() : "0"));
// LINQ to Entities 無法轉換資料庫欄位的 .ToString(),改為整數陣列比較
var allowedCategories = new[] { 1, 2, 4 };
qry = qry.Where(o => allowedCategories.Contains(o.category ?? 0)); //報名,掛單,贊助
qry = qry.OrderByDescending(o => o.num);
var count = qry.Count(); //pageSize = count;//一次取回??
var qryList = (pageSize > 0) ? qry.ToPagedList(page, pageSize).ToList() : qry.ToList();
@@ -1377,6 +1391,9 @@ public class activityController : ApiController
}
else if (sortBy.Equals("reg_time_time"))
{
// ⚠️ 警告: TimeOfDay 屬性在某些 Entity Framework 版本中可能不支援
// 如果發生 System.NotSupportedException需改為先 ToList() 再排序
// 目前如果正常運作,則資料庫提供者支援此操作
if (sortDesc)
qry = qry.OrderByDescending(o => o.reg_time.Value.TimeOfDay);
else

View File

@@ -96,13 +96,14 @@ public class bed_kindController : ApiController
qry = qry.Where(o => o.bed_type == q.bed_type);
if (!string.IsNullOrEmpty(q.bed_type_txt))
{
List<string> _bednums = new List<string>();
// ❌ 錯誤寫法: List<string> _bednums = new List<string>(); _bednums.Add(ii.Key.ToString()); qry = qry.Where(o => _bednums.Contains(o.bed_type.Value.ToString()));
// LINQ to Entities 無法轉換資料庫欄位的 .ToString(),改為整數陣列比較
List<int> _bednums = new List<int>();
foreach (var ii in tdesc)
if(ii.Value.IndexOf(q.bed_type_txt) > -1)
_bednums.Add(ii.Key.ToString());
_bednums.Add(ii.Key);
qry = qry.Where(o => _bednums.Contains( o.bed_type.Value.ToString()));
qry = qry.Where(o => _bednums.Contains(o.bed_type ?? 0));
}
if (q.inTime.HasValue )
{

View File

@@ -140,7 +140,9 @@ public class orderController : ApiController
var prod = _db.pro_order.Where(q => ids.Contains(q.order_no)).ToList();
if (prod.Count() > 0)
{
var prod2 = _db.pro_order_detail.Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
// ❌ 錯誤寫法: var prod2 = _db.pro_order_detail.Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
// LINQ to Entities 無法轉換 Convert.ToString() 方法,必須先取出資料再用 LINQ to Objects 過濾
var prod2 = _db.pro_order_detail.ToList().Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
if (prod2.Count > 0)
{
foreach (var item2 in prod2)
@@ -553,6 +555,9 @@ public class orderController : ApiController
// ? qry2a.OrderByDescending(ar => ar.num)
// : qry2a.OrderBy(ar => ar.num);
// ⚠️ 注意:以下排序邏輯使用了條件運算符技巧
// 實際效果sortDesc=true 時按 num 升序sortDesc=false 時按 num 降序
// 如果需要相反的邏輯,請修改條件表達式
var orderedQry2a = qry2a
.OrderByDescending(ar => ar.isPackage) // Ensure top-level items come first
.ThenBy(ar => sortDesc ? 0 : 1) // This is a trick to conditionally switch between ThenBy and ThenByDescending

View File

@@ -319,6 +319,8 @@ public class pivotController : ApiController
total_followers = g.Select(x => x.FollowerNum).Distinct().Count(),
total_amount = g.Sum(x => x.Amount),
total_qty = g.Sum(x => x.Qty),
// ⚠️ 複雜聚合:巢狀 GroupBy → Average → SumEF 6.4.4 可轉換
// 如遇到 NotSupportedException改為在 .ToList() 後計算
avg_amount_per_follower = g.GroupBy(x => x.FollowerNum).Average(fg => fg.Sum(x => x.Amount))
})
.OrderByDescending(x => x.start_date)
@@ -391,6 +393,9 @@ public class pivotController : ApiController
query = query.Where(x => x.FollowerNum == followerNum.Value);
}
// ✅ 優化:先取得總活動數,避免在投影中跨表查詢
var totalActivitiesCount = _db.activities.Count();
// 信眾統計分析
var followerStats = query.GroupBy(x => new { x.FollowerNum, x.FollowerName, x.FollowerCode })
.Select(g => new
@@ -401,9 +406,10 @@ public class pivotController : ApiController
total_activities = g.Select(x => x.ActivityNum).Distinct().Count(),
total_amount = g.Sum(x => x.Amount),
total_orders = g.Select(x => x.OrderDate).Count(),
// ⚠️ 複雜聚合:巢狀 GroupBy → Average → SumEF 6.4.4 可轉換
// 如遇到 NotSupportedException改為在 .ToList() 後計算
avg_amount_per_activity = g.GroupBy(x => x.ActivityNum).Average(ag => ag.Sum(x => x.Amount)),
is_patron_count = g.Count(x => x.HasParent),
participation_rate = Math.Round((double)g.Select(x => x.ActivityNum).Distinct().Count() / _db.activities.Count() * 100, 2),
favorite_kinds = g.GroupBy(x => x.KindName)
.OrderByDescending(kg => kg.Sum(x => x.Amount))
.Take(3)
@@ -419,6 +425,22 @@ public class pivotController : ApiController
.ToList()
})
.OrderByDescending(x => x.total_amount)
.ToList()
// ✅ 優化:在記憶體中計算 participation_rate避免 Math.Round 在 LINQ to Entities 投影中
.Select(x => new
{
x.follower_num,
x.follower_name,
x.follower_code,
x.total_activities,
x.total_amount,
x.total_orders,
x.avg_amount_per_activity,
x.is_patron_count,
participation_rate = Math.Round((double)x.total_activities / totalActivitiesCount * 100, 2),
x.favorite_kinds,
x.recent_activities
})
.ToList();
var result = new
@@ -527,35 +549,31 @@ public class pivotController : ApiController
break;
case "activity":
stats = query.GroupBy(x => new { x.ActivityNum, x.ActivityName, x.StartDate })
// ✅ 優化:一次性取出所有資料,避免 N+1 查詢
var activityData = query.ToList();
stats = activityData.GroupBy(x => new { x.ActivityNum, x.ActivityName, x.StartDate })
.Select(g => new
{
activity_num = g.Key.ActivityNum,
activity_name = g.Key.ActivityName,
start_date = g.Key.StartDate,
total_amount = g.Sum(x => x.Amount)
total_amount = g.Sum(x => x.Amount),
// ✅ 優化:在記憶體中分組,避免子查詢
kind_breakdown = g.GroupBy(x => x.KindName)
.Select(kg => new
{
kind = kg.Key,
amount = kg.Sum(x => x.Amount),
// ✅ 優化:在記憶體中計算百分比
percentage = g.Sum(x => x.Amount) > 0
? Math.Round((double)kg.Sum(x => x.Amount) / (double)g.Sum(x => x.Amount) * 100, 2)
: 0
})
.OrderByDescending(x => x.amount)
.ToList()
})
.OrderByDescending(x => x.start_date)
.ToList()
.Select(g => new
{
g.activity_num,
g.activity_name,
g.start_date,
g.total_amount,
kind_breakdown = query.Where(x => x.ActivityNum == g.activity_num)
.GroupBy(x => x.KindName)
.Select(kg => new
{
kind = kg.Key,
amount = kg.Sum(x => x.Amount),
percentage = g.total_amount.HasValue && g.total_amount.Value > 0
? Math.Round((double)(kg.Sum(x => x.Amount) ?? 0) / (double)g.total_amount.Value * 100, 2)
: 0
})
.OrderByDescending(x => x.amount)
.ToList()
})
.ToList();
break;

View File

@@ -111,6 +111,9 @@ public class statisticsController: ApiController
price = g.Key.price,
count = g.Count(),//功德項目的數量
total_price = g.Where(x => x.price != null).Sum(x => x.price),
// ⚠️ 潛在 N+1 查詢:在 GroupBy 投影中執行新查詢
// g.Select(...).ToList() 會立即執行,然後用 Contains 做子查詢
// 若 g 數量很多,建議重構為 join 或分兩階段查詢以提升效能
followers = _db.pro_order
.Where(h => g.Select(x => x.order_no).Distinct().ToList().Contains(h.order_no))
.Select(k => k.follower.u_name)

View File

@@ -135,7 +135,9 @@ public class apporderController : ApiController
var prod = _db.pro_order.Where(q => ids.Contains(q.order_no)).ToList();
if (prod.Count() > 0)
{
var prod2 = _db.pro_order_detail.Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
// ❌ 錯誤寫法: var prod2 = _db.pro_order_detail.Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
// LINQ to Entities 無法轉換 Convert.ToString() 方法,必須先取出資料再用 LINQ to Objects 過濾
var prod2 = _db.pro_order_detail.ToList().Where(q => ids.Contains(Convert.ToString(q.order_no))).ToList();
if (prod2.Count > 0)
{
foreach (var item2 in prod2)

View File

@@ -258,8 +258,12 @@ public partial class admin_hr_import : MyWeb.config
int f_num = fDt.Where(x => x.f_number == ValString(sheet.Cells[currentRow, 1].Text.Trim())).Select(x => x.num).FirstOrDefault(); //信眾編號id
int a_num = aDt.Where(x => x.u_id == ValString(sheet.Cells[currentRow, 12].Text.Trim())).Select(x => x.num).FirstOrDefault(); //系統帳號id
int g_sum = gDt.Where(x => x.ToString() == ValString(sheet.Cells[currentRow, 16].Text.Trim())).FirstOrDefault(); //組別
int t_sum = tDt.Where(x => x.ToString() == ValString(sheet.Cells[currentRow, 17].Text.Trim())).FirstOrDefault(); //職稱
// ❌ 錯誤寫法: int g_sum = gDt.Where(x => x.ToString() == ValString(...)).FirstOrDefault();
// 應該先轉換為整數再比較,避免不必要的字串轉換
int.TryParse(ValString(sheet.Cells[currentRow, 16].Text.Trim()), out int g_sum_parsed);
int g_sum = gDt.Contains(g_sum_parsed) ? g_sum_parsed : 0; //組別
int.TryParse(ValString(sheet.Cells[currentRow, 17].Text.Trim()), out int t_sum_parsed);
int t_sum = tDt.Contains(t_sum_parsed) ? t_sum_parsed : 0; //職稱
//定義日期欄位格式
sheet.Cells[currentRow, 6].Style.Numberformat.Format = "yyyy-MM-dd";

View File

@@ -104,7 +104,9 @@ public partial class admin_activity_index2 : MyWeb.config
sd.AppendChild(tr);
//查詢要匯出的資料
var fileDt = _db.files.Where(f => f.subject.Contains(fileTxt.Value)).Select(f => f.num.ToString());//文件
// ❌ 錯誤寫法: var fileDt = _db.files.Where(f => f.subject.Contains(fileTxt.Value)).Select(f => f.num.ToString());
// 改為整數陣列,避免後續查詢中使用 .ToString()
var fileDt = _db.files.Where(f => f.subject.Contains(fileTxt.Value)).Select(f => f.num).ToArray();//文件
var qry = _db.actItems.AsQueryable();
@@ -139,7 +141,11 @@ public partial class admin_activity_index2 : MyWeb.config
if (!string.IsNullOrEmpty(s_kind.SelectedValue))
qry = qry.Where(o => o.kind == Convert.ToInt32(s_kind.SelectedValue));
if (!string.IsNullOrEmpty(fileTxt.Value))
qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && fileDt.ToArray().Contains(f2.files_num.ToString())).Count() > 0);
{
// ❌ 錯誤寫法: qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && fileDt.ToArray().Contains(f2.files_num.ToString())).Count() > 0);
// fileDt 已改為整數陣列,直接比較即可
qry = qry.Where(o => o.actItem_files.Where(f2 => f2.actItem_num == o.num && fileDt.Contains(f2.files_num)).Count() > 0);
}
var tdesc = publicFun.enum_desc<Model.activity.category>();
qry = qry.OrderByDescending(o => o.num);

View File

@@ -26,63 +26,79 @@ public partial class admin_follower_print_ : System.Web.UI.Page
//紀錄匯出條件
string _query = "";
var qry = _db.followers.AsQueryable();
if (!string.IsNullOrEmpty(Request["f_number"]))
// ❌ 錯誤寫法: qry = qry.Where(o => o.f_number.Contains(Request["f_number"].Trim()));
// LINQ to Entities 無法轉換 Request[] 方法,必須先轉換為變數再使用
string fNumberParam = Request["f_number"]?.Trim();
if (!string.IsNullOrEmpty(fNumberParam))
{
qry = qry.Where(o => o.f_number.Contains(Request["f_number"].Trim()));
_query += "信眾編號:" + Request["f_number"].Trim() + "\n";
qry = qry.Where(o => o.f_number.Contains(fNumberParam));
_query += "信眾編號:" + fNumberParam + "\n";
}
if (!string.IsNullOrEmpty(Request["u_name"]))
string uNameParam = Request["u_name"]?.Trim();
if (!string.IsNullOrEmpty(uNameParam))
{
qry = qry.Where(o => o.u_name.Contains(Request["u_name"].Trim()));
_query += "信眾姓名:" + Request["u_name"].Trim() + "\n";
qry = qry.Where(o => o.u_name.Contains(uNameParam));
_query += "信眾姓名:" + uNameParam + "\n";
}
if (!string.IsNullOrEmpty(Request["address"]))
string addressParam = Request["address"]?.Trim();
if (!string.IsNullOrEmpty(addressParam))
{
qry = qry.Where(o => o.address.Contains(Request["address"].Trim()));
_query += "地址:" + Request["address"].Trim() + "\n";
qry = qry.Where(o => o.address.Contains(addressParam));
_query += "地址:" + addressParam + "\n";
}
if (!string.IsNullOrEmpty(Request["birthday"]))
{
qry = qry.Where(o => o.birthday >= Convert.ToDateTime(Request["birthday"].Trim()));
_query += "生日(起):" + Convert.ToDateTime(Request["birthday"].Trim()).ToString("yyyy/MM/dd") + "\n";
DateTime birthdayParam = Convert.ToDateTime(Request["birthday"].Trim());
qry = qry.Where(o => o.birthday >= birthdayParam);
_query += "生日(起):" + birthdayParam.ToString("yyyy/MM/dd") + "\n";
}
if (!string.IsNullOrEmpty(Request["birthday2"]) )
if (!string.IsNullOrEmpty(Request["birthday2"]))
{
qry = qry.Where(o => o.birthday < Convert.ToDateTime(Request["birthday2"]).AddDays(1));
_query += "生日(訖):" + Convert.ToDateTime(Request["birthday2"].Trim()).ToString("yyyy/MM/dd") + "\n";
DateTime birthday2Param = Convert.ToDateTime(Request["birthday2"].Trim());
qry = qry.Where(o => o.birthday < birthday2Param.AddDays(1));
_query += "生日(訖):" + birthday2Param.ToString("yyyy/MM/dd") + "\n";
}
if (!string.IsNullOrEmpty(Request["country"]))
// ❌ 錯誤寫法: _db.countries.Where(x => x.ID == Request["country"].ToString())
// LINQ to Entities 無法轉換 Request[].ToString(),必須先轉換為變數再使用
string countryId = Request["country"]?.ToString();
if (!string.IsNullOrEmpty(countryId))
{
qry = qry.Where(o => o.country == Request["country"]);
_query += "國家:" + (_db.countries.Where(x => x.ID == Request["country"].ToString()).Select(x => x.name_zh).FirstOrDefault()??"" )+ "\n";
qry = qry.Where(o => o.country == countryId);
_query += "國家:" + (_db.countries.Where(x => x.ID == countryId).Select(x => x.name_zh).FirstOrDefault() ?? "") + "\n";
}
if (!string.IsNullOrEmpty(Request["country2"]))
string country2Id = Request["country2"]?.ToString();
if (!string.IsNullOrEmpty(country2Id))
{
if (Request["country2"] == "1")
if (country2Id == "1")
{
qry = qry.Where(o => o.country == "158");
qry = qry.Where(o => o.country == "158");
}
else if (Request["country2"] == "2")
else if (country2Id == "2")
{
qry = qry.Where(o => o.country != "158");
qry = qry.Where(o => o.country != "158");
}
_query += "國家:" + (_db.countries.Where(x => x.ID == Request["country2"].ToString()).Select(x => x.name_zh).FirstOrDefault()??"") + "\n";
_query += "國家:" + (_db.countries.Where(x => x.ID == country2Id).Select(x => x.name_zh).FirstOrDefault() ?? "") + "\n";
}
//管理報表
if (!string.IsNullOrEmpty(Request["year"]))
{
//title.Text = "信眾管理報表";
qry = qry.Where(o => o.join_date.HasValue && o.join_date.Value.Year == Convert.ToInt32(Request["year"]) );
//title.Text = "信眾管理報表";
int yearParam = Convert.ToInt32(Request["year"]);
qry = qry.Where(o => o.join_date.HasValue && o.join_date.Value.Year == yearParam);
_query += "年份:" + Request["year"] + "\n";
}
if (!string.IsNullOrEmpty(Request["month"]))
{
qry = qry.Where(o => o.join_date.HasValue && o.join_date.Value.Month == Convert.ToInt32(Request["month"]));
int monthParam = Convert.ToInt32(Request["month"]);
qry = qry.Where(o => o.join_date.HasValue && o.join_date.Value.Month == monthParam);
_query += "月份:" + Request["month"] + "\n";
}
if (!string.IsNullOrEmpty(Request["season"]) )

View File

@@ -31,8 +31,13 @@ public partial class admin_bed_new_reg : MyWeb.config
keyin1.Items.Add(item);
}
// ❌ 錯誤寫法: var prod = qry.Where(q => q.order_no == Request["order_no"].ToString() && q.o_detail_id == Convert.ToInt32(Request["detail"])).FirstOrDefault();
// LINQ to Entities 無法轉換 Request 和 Convert 方法,必須先轉換為變數再使用
string orderNo = Request["order_no"]?.ToString();
int detailId = Convert.ToInt32(Request["detail"]);
var qry = _db.bed_order.AsQueryable();
var prod = qry.Where(q => q.order_no == Request["order_no"].ToString() && q.o_detail_id == Convert.ToInt32(Request["detail"])).FirstOrDefault();
var prod = qry.Where(q => q.order_no == orderNo && q.o_detail_id == detailId).FirstOrDefault();
if (prod != null)
{
bed_order_no.Text = prod.bed_order_no.ToString();

View File

@@ -128,7 +128,9 @@ public partial class admin_order_index : MyWeb.config
sd.AppendChild(tr);
//查詢要匯出的資料
var aIDt = _db.actItems.Where(f => f.subject.Contains(s_actItemTxt.Value.Trim())).Select(f => f.num.ToString());//品項
// ❌ 錯誤寫法: var aIDt = _db.actItems.Where(f => f.subject.Contains(s_actItemTxt.Value.Trim())).Select(f => f.num.ToString());
// 改為整數陣列,避免後續查詢中使用 .ToString()
var aIDt = _db.actItems.Where(f => f.subject.Contains(s_actItemTxt.Value.Trim())).Select(f => f.num).ToArray();//品項
var qry = _db.pro_order.AsQueryable();
if (!isStrNull(s_order_no.Value))
@@ -140,7 +142,14 @@ public partial class admin_order_index : MyWeb.config
if (!isStrNull(s_subject.Value))
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(s_subject.Value.Trim()));
if (!isStrNull(s_actItemTxt.Value))
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num.ToString())).Count() > 0);
{
// ❌ 錯誤寫法: qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.order_no == o.order_no && aIDt.ToArray().Contains(f2.actItem_num.ToString())).Count() > 0);
// ✅ 實際比較:僅在 actItem_num 有值時才與整數陣列比對
qry = qry.Where(o => o.pro_order_detail.Any(f2 =>
f2.order_no == o.order_no &&
f2.actItem_num.HasValue &&
aIDt.Contains(f2.actItem_num.Value)));
}
if (!isStrNull(s_keyin1.SelectedValue))
qry = qry.Where(o => o.keyin1 == s_keyin1.SelectedValue);

View File

@@ -26,68 +26,91 @@ public partial class admin_follower_print_ : System.Web.UI.Page
//紀錄匯出條件
string _query = "";
var qry = _db.pro_order.AsQueryable();
if (!string.IsNullOrEmpty(Request["order_no"]))
// ❌ 錯誤寫法: qry = qry.Where(o => o.order_no.Contains(Request["order_no"].Trim()));
// LINQ to Entities 無法轉換 Request[] 方法,必須先轉換為變數再使用
string orderNoParam = Request["order_no"]?.Trim();
if (!string.IsNullOrEmpty(orderNoParam))
{
qry = qry.Where(o => o.order_no.Contains(Request["order_no"].Trim()));
_query += "單號:" + Request["order_no"].Trim() + "\n";
qry = qry.Where(o => o.order_no.Contains(orderNoParam));
_query += "單號:" + orderNoParam + "\n";
}
if (!string.IsNullOrEmpty(Request["subject"]))
string subjectParam = Request["subject"]?.Trim();
if (!string.IsNullOrEmpty(subjectParam))
{
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(Request["subject"].Trim()));
_query += "報名活動:" + Request["subject"].Trim() + "\n";
qry = qry.Where(o => o.activity_num.HasValue && o.activity.subject.Contains(subjectParam));
_query += "報名活動:" + subjectParam + "\n";
}
if (!string.IsNullOrEmpty(Request["u_name"]))
string uNameParam = Request["u_name"]?.Trim();
if (!string.IsNullOrEmpty(uNameParam))
{
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(Request["u_name"].Trim()));
_query += "姓名/名稱:" + Request["u_name"].Trim() + "\n";
qry = qry.Where(o => o.f_num.HasValue && o.follower.u_name.Contains(uNameParam));
_query += "姓名/名稱:" + uNameParam + "\n";
}
if (!string.IsNullOrEmpty(Request["introducerTxt"]))
string introducerParam = Request["introducerTxt"]?.Trim();
if (!string.IsNullOrEmpty(introducerParam))
{
qry = qry.Where(o => o.introducer.HasValue && o.follower1.u_name.Contains(Request["introducerTxt"].Trim()));
_query += "介紹人:" + Request["introducerTxt"].Trim() + "\n";
qry = qry.Where(o => o.introducer.HasValue && o.follower1.u_name.Contains(introducerParam));
_query += "介紹人:" + introducerParam + "\n";
}
if (!string.IsNullOrEmpty(Request["actItemTxt"]))
string actItemParam = Request["actItemTxt"]?.Trim();
if (!string.IsNullOrEmpty(actItemParam))
{
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem.subject.Contains(Request["actItemTxt"].Trim()) ).Count() > 0);
_query += "品項:" + Request["actItemTxt"].Trim() + "\n";
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem.subject.Contains(actItemParam)).Count() > 0);
_query += "品項:" + actItemParam + "\n";
}
if (!string.IsNullOrEmpty(Request["keyin1"]))
{
qry = qry.Where(o => o.keyin1==Request["keyin1"].ToString());
// ❌ 錯誤寫法: qry = qry.Where(o => o.keyin1==Request["keyin1"].ToString());
// LINQ to Entities 無法轉換 Request[].ToString(),必須先轉換為變數再使用
string keyin1Value = Request["keyin1"]?.ToString();
qry = qry.Where(o => o.keyin1 == keyin1Value);
_query += "單據狀態:" + Model.pro_order.keyin1_value_to_text( Request["keyin1"].Trim()) + "\n";
}
if (!string.IsNullOrEmpty(Request["address"]))
string addressParam = Request["address"]?.Trim();
if (!string.IsNullOrEmpty(addressParam))
{
qry = qry.Where(o => o.address.Contains(Request["address"].Trim()));
_query += "地址:" + Request["address"].Trim() + "\n";
qry = qry.Where(o => o.address.Contains(addressParam));
_query += "地址:" + addressParam + "\n";
}
if (!string.IsNullOrEmpty(Request["up_time1"]))
{
qry = qry.Where(o => o.up_time >= Convert.ToDateTime(Request["up_time1"].Trim()));
_query += "報名日期(起):" + Convert.ToDateTime(Request["up_time1"].Trim()).ToString("yyyy/MM/dd") + "\n";
DateTime upTime1Param = Convert.ToDateTime(Request["up_time1"].Trim());
qry = qry.Where(o => o.up_time >= upTime1Param);
_query += "報名日期(起):" + upTime1Param.ToString("yyyy/MM/dd") + "\n";
}
if (!string.IsNullOrEmpty(Request["up_time2"]) )
if (!string.IsNullOrEmpty(Request["up_time2"]))
{
qry = qry.Where(o => o.up_time < Convert.ToDateTime(Request["up_time2"]).AddDays(1));
_query += "報名日期(訖):" + Convert.ToDateTime(Request["up_time2"].Trim()).ToString("yyyy/MM/dd") + "\n";
DateTime upTime2Param = Convert.ToDateTime(Request["up_time2"].Trim());
qry = qry.Where(o => o.up_time < upTime2Param.AddDays(1));
_query += "報名日期(訖):" + upTime2Param.ToString("yyyy/MM/dd") + "\n";
}
if (!string.IsNullOrEmpty(Request["country"]))
string countryParam = Request["country"]?.ToString();
if (!string.IsNullOrEmpty(countryParam))
{
qry = qry.Where(o => o.f_num != null && o.follower.country == Request["country"]);
_query += "國家:" + (_db.countries.Where(x => x.ID == Request["country"]).Select(x => x.name_zh).FirstOrDefault()??"") + "\n";
qry = qry.Where(o => o.f_num != null && o.follower.country == countryParam);
_query += "國家:" + (_db.countries.Where(x => x.ID == countryParam).Select(x => x.name_zh).FirstOrDefault() ?? "") + "\n";
}
if (!string.IsNullOrEmpty(Request["country2"]))
string country2Param = Request["country2"]?.ToString();
if (!string.IsNullOrEmpty(country2Param))
{
if (Request["country2"] == "1")
if (country2Param == "1")
{
qry = qry.Where(o => o.f_num != null && o.follower.country == "158");
}
else if (Request["country2"] == "2")
else if (country2Param == "2")
{
qry = qry.Where(o => o.f_num != null && o.follower.country != "158");
}
_query += "國家:" + (_db.countries.Where(x => x.ID == Request["country2"]).Select(x => x.name_zh).FirstOrDefault()??"") + "\n";
_query += "國家:" + (_db.countries.Where(x => x.ID == country2Param).Select(x => x.name_zh).FirstOrDefault() ?? "") + "\n";
}
if (!string.IsNullOrEmpty(Request["hasPrice"]))
{
@@ -105,12 +128,15 @@ public partial class admin_follower_print_ : System.Web.UI.Page
if (!string.IsNullOrEmpty(Request["year"]))
{
title.Text = "報名管理報表";
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Year == Convert.ToInt32(Request["year"]));
int yearParam = Convert.ToInt32(Request["year"]);
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Year == yearParam);
_query += "年份:" + Request["year"] + "\n";
}
if (!string.IsNullOrEmpty(Request["month"]))
{
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Month == Convert.ToInt32(Request["month"]));
int monthParam = Convert.ToInt32(Request["month"]);
qry = qry.Where(o => o.up_time.HasValue && o.up_time.Value.Month == monthParam);
_query += "月份:" + Request["month"] + "\n";
}
if (!string.IsNullOrEmpty(Request["season"]))
@@ -139,24 +165,32 @@ public partial class admin_follower_print_ : System.Web.UI.Page
_query += "季度:" + Request["season"] + "\n";
}
if (!string.IsNullOrEmpty(Request["chk_hasact"]) && Convert.ToBoolean(Request["chk_hasact"]) )
if (!string.IsNullOrEmpty(Request["chk_hasact"]) && Convert.ToBoolean(Request["chk_hasact"]))
{
_query += "活動報名\n";
if (!string.IsNullOrEmpty(Request["chk_noact"]) && Convert.ToBoolean(Request["chk_noact"]))
{
_query += "非活動報名\n";
if (!string.IsNullOrEmpty(Request["select_act"]) && Convert.ToInt32(Request["select_act"]) > 0)
if (!string.IsNullOrEmpty(Request["select_act"]))
{
qry = qry.Where(o => o.activity_num.HasValue && o.activity_num.Value == Convert.ToInt32(Request["select_act"]));
int selectActParam = Convert.ToInt32(Request["select_act"]);
if (selectActParam > 0)
{
qry = qry.Where(o => o.activity_num.HasValue && o.activity_num.Value == selectActParam);
}
}
}
else
{
qry = qry.Where(o => o.activity_num.HasValue);
if (!string.IsNullOrEmpty(Request["select_act"]) && Convert.ToInt32(Request["select_act"]) > 0)
if (!string.IsNullOrEmpty(Request["select_act"]))
{
qry = qry.Where(o => o.activity_num.Value == Convert.ToInt32(Request["select_act"]));
int selectActParam = Convert.ToInt32(Request["select_act"]);
if (selectActParam > 0)
{
qry = qry.Where(o => o.activity_num.Value == selectActParam);
}
}
}
@@ -165,13 +199,18 @@ public partial class admin_follower_print_ : System.Web.UI.Page
{
if (!string.IsNullOrEmpty(Request["chk_noact"]) && Convert.ToBoolean(Request["chk_noact"]))
{
qry = qry.Where(o => o.activity_num==null);
qry = qry.Where(o => o.activity_num == null);
_query += "非活動報名\n";
}
}
if (!string.IsNullOrEmpty(Request["select_actitem"]) && Convert.ToInt32(Request["select_actitem"]) > 0)
if (!string.IsNullOrEmpty(Request["select_actitem"]))
{
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem_num.Value == Convert.ToInt32(Request["select_actitem"])).Count() > 0);
int selectActItemParam = Convert.ToInt32(Request["select_actitem"]);
if (selectActItemParam > 0)
{
qry = qry.Where(o => o.pro_order_detail.Where(f2 => f2.actItem_num.HasValue && f2.actItem_num.Value == selectActItemParam).Count() > 0);
}
}
if (!string.IsNullOrEmpty(Request["year"]))

View File

@@ -42,9 +42,12 @@ public partial class admin_order_reg : MyWeb.config
}
else
{
// ❌ 錯誤寫法: var prod = qry.Where(q => q.order_no == Convert.ToString(Request["order_no"])).FirstOrDefault();
// LINQ to Entities 無法轉換 Convert.ToString() 方法,必須先轉換為變數再使用
string orderNo = Convert.ToString(Request["order_no"]);
var qry = _db.pro_order.AsQueryable();
var prod = qry.Where(q => q.order_no == Convert.ToString(Request["order_no"])).FirstOrDefault();
var prod = qry.Where(q => q.order_no == orderNo).FirstOrDefault();
if (prod != null)
{
MyWeb.encrypt encrypt = new MyWeb.encrypt();