我有兩個串列,一個包含來自客戶端的資料,另一個來自我的資料庫,這意味著這些資料已經包含在我的資料庫中。
我想要做的是,根據我的客戶串列,用我的資料庫串列過濾它,只回傳不包含在我的資料庫中的資料,這樣我就可以在插入之前處理非重復的資料。
為了過濾此資料,我嘗試使用具有多個條件(銀行資料)的 LINQ。
private List<PrePaymentBalanceQuery> FiltraConsultasNaoProcessadas(List<InfoBancariaLoja> consultasAProcessar, List<PrePaymentBalanceQuery> consultasProcessadas)
{
List<BalanceQuery> result = new List<BalanceQuery>();
clientList.ForEach(y =>
{
result = dbList.Where(x =>
(y.BankCode != x.BankCode) ||
(y.Agency != x.Agency) ||
(y.AccountNumber != x.AccountNumber)).ToList();
});
return result;
}
但由于某種原因,它不能正常作業。任何的想法?
謝謝
uj5u.com熱心網友回復:
假設您有一個如下所示的類:
class CustomerInformation
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
正如您所說,您有兩個串列,假設您有兩個串列,如下所示:
List<CustomerInformation> dbList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"}
};
List<CustomerInformation> csutomerList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"},
new CustomerInformation{Id=5, FirstName="Anny", LastName="Bishwas"},
new CustomerInformation{Id=6, FirstName="Kabita", LastName="Roy"},
new CustomerInformation{Id=7, FirstName="Zahidul", LastName="Emon"}
};
現在,您希望通過某些特定條件獲取客戶串列中不存在的那些資料庫串列,因此請嘗試以下操作:
var newList = csutomerList.Where(cusItem => !dbList.Any(dbItem => cusItem.Id == dbItem.Id && cusItem.FirstName == dbItem.FirstName && cusItem.LastName == dbItem.LastName));
它將首先找出兩個串列中存在的所有資料,然后簡單地扣除它們。
示例輸出:

完整代碼在這里:
static void Main(string[] args)
{
AvailableData();
Console.ReadKey();
}
public static void AvailableData()
{
// Create two lists.
List<CustomerInformation> dbList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"}
};
List<CustomerInformation> csutomerList = new List<CustomerInformation>
{
new CustomerInformation{Id=1, FirstName="Raju", LastName="Ahmed"},
new CustomerInformation{Id=2, FirstName="Tahira", LastName="Biswas"},
new CustomerInformation{Id=3, FirstName="Shohag", LastName="Mia"},
new CustomerInformation{Id=4, FirstName="Saiful", LastName="Islam"},
new CustomerInformation{Id=5, FirstName="Anny", LastName="Bishwas"},
new CustomerInformation{Id=6, FirstName="Kabita", LastName="Roy"},
new CustomerInformation{Id=7, FirstName="Zahidul", LastName="Emon"}
};
var newList = csutomerList.Where(cusItem => !dbList.Any(dbItem => cusItem.Id == dbItem.Id && cusItem.FirstName == dbItem.FirstName && cusItem.LastName == dbItem.LastName));
foreach (var cust in newList)
{
Console.WriteLine("Customer Id :{0} | Customer Name: {1} | Last Name: {2} ",cust.Id,cust.FirstName,cust.LastName);
}
Console.ReadKey();
}
}
class CustomerInformation
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
uj5u.com熱心網友回復:
初步的
此答案假定您使用的是 ORM,例如 EF 或 EF Core。代碼沒有經過測驗,只是為了給你正確的方向來解決你的問題。需要回答一些懸而未決的問題才能得出最終解決方案。
此外,您的問題有時似乎自相矛盾:您提到的是客戶串列,而您顯示的函式回傳List<PrePaymentBalanceQuery>. 我假設在這里我們談論的是客戶名單,我可以撇開一些不清楚的地方。無論如何,如果我離開,請告訴我,我將編輯此答案或將其洗掉。
分析現有代碼和問題
既然代碼沒有做你想要的,讓我們首先了解它是做什么的。
您想Client根據存盤在資料庫中的一些資料過濾記憶體串列。
clientList.ForEach(y =>
{
result = dbList.Where(x =>
(y.BankCode != x.BankCode) ||
(y.Agency != x.Agency) ||
(y.AccountNumber != x.AccountNumber)).ToList();
});
return result;
此代碼不過濾Client串列。
它的作用是,對于每個Client:
- 計算一些東西并將其存盤到一個名為 的變數中
result。
因此,在每次連續迭代中,變數中的內容result都會被新內容替換。
最后,變數result只包含為最后一個客戶端所做的計算,這不是您想要實作的。
結論:你不應該ForEach在這里使用。ForEach不是過濾運算子。Linq 有一個過濾運算子: Where,這里應該使用它。
旁注:ForEach不是 Linq 方法擴展。它是List類的一個方法。乍一看似乎令人驚訝,但這是有充分理由的。ForEach不是純粹的(在函式式編程意義上),會引入副作用,因此違背了 Linq 的一般原則。在 Linq 中不強制執行純度,但通常是可取的。
如何嘗試解決這個問題
這是過濾的第一個版本clientList:
var FilteredClientList = clientList.Where(c => !dbList
.Any(dbc =>
(c.BankCode == dbc.BankCode)
&& (c.Agency == dbc.Agency)
&& (c.AccountNumber == dbc.AccountNumber))
);
return FilteredClientList;
它有什么作用?
clientList只有在資料庫中沒有這樣的客戶端時,它才會通過保留客戶端來構建新的客戶端串列。
如果存在具有相同Bankcode、相同Agency和相同的資料庫客戶端,則認為記憶體中客戶端在資料庫中AccountNumber。
However, there is a problem. While this works functionally, it makes potentially a lot of calls to your database: one for each client.
To understand this, you have to be aware of the difference between Linq to Objects and Linq to Entities.
See linq to entities vs linq to objects - are they the same?
How to fix this? it depends on your particular situation. If your client list is small, you could keep it that way, and be willing to pay for a SQL query for each of your clients.
If your database list is small, you could simply get it in memory first, and do all the work in memory.
var ClientsFromDb = dbList.
.Select(c => new
{
c.BankCode,
c.Agency,
c.AccountNumber
})
.ToList()
var FilteredClientList = clientList.Where(c => !ClientsFromDb
.Any(cc =>
(c.BankCode == cc.BankCode)
&& (c.Agency == cc.Agency)
&& (c.AccountNumber == cc.AccountNumber))
);
This might also be improved by the use of a Join operator.
But what if your database client list is too big?
您可以首先在一個資料庫查詢中檢索資料庫中所有匹配的客戶端,然后使用該記憶體串列來過濾您的實際串列。
請參閱本地序列不能在查詢運算子的 LINQ to SQL 實作中使用,但用于指標的 Contains() 運算子除外。
uj5u.com熱心網友回復:
更多的 LINQ 方法會像。它是從我這邊測驗的。
result =
(from cl in clientList
where !dbList.Any(x => x.AccountNumber == cl.AccountNumber && x.BankCode == cl.BankCode && x.Agency == cl.Agency)
select cl).ToList();
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/352931.html
