检查数组是否包含在LINQ表达式中的数组数组中
本文关键字:数组 表达式 LINQ 是否 包含 检查 | 更新日期: 2025-01-25 10:49:13
我的单元测试有一些问题,它使用伪上下文(意味着没有数据库连接)。在生产环境中,它与sql连接,一切都很清楚。但是,在伪造上下文的情况下,发生了一些奇怪的事情——在数组"validCardItems"的数组中找不到数组"item.OfferKey"
//Array of arrays validCartItems values for example
byte[] offerKey1 = { 30, 163, 252, 225, 36, 208, 128, 47, 64, 244, 34, 199, 28, 57, 110, 215 };
byte[] offerKey2 = { 31, 163, 254, 225, 35, 203, 119, 47, 65, 244, 24, 199, 28, 56, 110, 215 };
byte[][] validCartItems = new byte[4][];
validCartItems[0] = offerKey1;
validCartItems[1] = offerKey1;
validCartItems[2] = offerKey1;
validCartItems[3] = offerKey2;
//Example of ItemPrice in _dataContext.ItemPrices
var itemPriceInFakeContext = new ItemPrice()
{
OfferKey = offerKey1,
//some other properties
};
var itemPrices = _dataContext
.ItemPrices
.Where(item =>
item.UserID == user.UniqueID
&& itemsPartID.Contains(item.PartID)
&& validCartItems.Contains(item.OfferKey)
&& item.CurrencyID == defaultCurrencyCode
&& item.Inventory > 0)
.ToList();
在这种情况下,找不到任何元素。但如果我们使用数据库,那么一切都可以。
为了解决这个问题,我写了以下代码:
var itemPricesUncheckOfferKey = _dataContext
.ItemPrices
.Where(item =>
item.UserID == user.UniqueID
&& itemsPartID.Contains(item.PartID)
//&& validCartItems.Contains(item.OfferKey)
&& item.CurrencyID == defaultCurrencyCode
&& item.Inventory > 0)
.ToList();
List<ItemPrice> itemPrices = new List<ItemPrice>();
foreach (var itemPrice in itemPricesUncheckOfferKey)
{
foreach (var validCartItem in validCartItems.Distinct())
{
if (validCartItem.SequenceEqual(itemPrice.OfferKey))
itemPrices.Add(itemPrice);
}
}
但这看起来并不是一个好的解决方案。你能告诉我LINQ的解决方案吗?
UPD-
UnitTest代码:
[TestMethod]
public void AddCartItems_Test()
{
User user;
InitUser(out user);
List<AddCartItem> addCartItems;
addCartItems = InitAddCartItem();
ICartService cartService;
InitCartService(out cartService);
List<AddCartItemRezult> addCartItemRezults = cartService.AddCartItems(user, addCartItems);
Assert.AreEqual(4, addCartItemRezults.Count);
int countAllGood = 0;
foreach (var addCartItemRezult in addCartItemRezults)
{
if (addCartItemRezult.IsSuccess) countAllGood++;
}
Assert.AreEqual(1, countAllGood);
}
private void InitCartService(out ICartService cartService )
{
DataFakeContext dataFakeContext = new DataFakeContext();
DataContext_InitUsers(ref dataFakeContext);
DataContext_ItemPrices(ref dataFakeContext);
DataContext_CartItems(ref dataFakeContext);
IDeliveryService deliveryService = new DeliveryFakeService(dataFakeContext);
cartService = new CartService(dataFakeContext, deliveryService);
}
private void DataContext_ItemPrices(ref DataFakeContext dataFakeContext)
{
dataFakeContext.ItemPrices = new ItemPriceDbSet();
byte[] OfferKeyPriv = { 30, 163, 252, 225, 36, 208, 128, 47, 64, 244, 34, 199, 28, 57, 110, 215 };
var itemPrice1 = new DataAccess.Sql.NavisionModel.ItemPrice()
{
Inventory = 2075,
ItemID = "475931",
LineAmount = (decimal)389.9300,
LineAmountWithMargin = (decimal)522.5062,
Multiplicity = 1,
OfferKey = OfferKeyPriv,
//some other properties
};
dataFakeContext.ItemPrices.Add(itemPrice1);
}
我使用Repository.Pattern.Ef6;
在代码中创建byte[] offerKey1 = ...
并将其保存到itemPriceInFakeContext
中。您应该使用相同的变量将其添加到_dataContext中。我的意思是完全相同-不是保存值,而是对同一对象的引用。
像这样:
//Array of arrays validCartItems values for example
byte[] offerKey1 = { 30, 163, 252, 225, 36, 208, 128, 47, 64, 244, 34, 199, 28, 57, 110, 215 };
byte[] offerKey2 = { 31, 163, 254, 225, 35, 203, 119, 47, 65, 244, 24, 199, 28, 56, 110, 215 };
byte[][] validCartItems = new byte[4][];
validCartItems[0] = offerKey1;
validCartItems[1] = offerKey1;
validCartItems[2] = offerKey1;
validCartItems[3] = offerKey2;
//Example of ItemPrice in _dataContext.ItemPrices
var itemPriceInFakeContext = new ItemPrice()
{
OfferKey = offerKey1, // use the same object
//some other properties
};
// add fake item price to data context
_dataContext.ItemPrices.Add(itemPriceInFakeContext );
var itemPrices = _dataContext
.ItemPrices
.Where(item =>
item.UserID == user.UniqueID
&& itemsPartID.Contains(item.PartID)
&& validCartItems.Contains(item.OfferKey)
&& item.CurrencyID == defaultCurrencyCode
&& item.Inventory > 0)
.ToList();
这应该会有所帮助。
p.s.您遇到这个问题是因为运行时比较byte[]
的方式与执行EF
和SQL
的方式之间存在差异。在运行时,它通过引用进行比较。但是您的LINQ查询(在执行时)将这个byte[]
数组(我相信)转换为字符串。在SQL端,它比较将按值进行比较的字符串。
var itemPrices = _dataContext
.ItemPrices
.Where(item =>
item.UserID == user.UniqueID
&& itemsPartID.Contains(item.PartID)
&& validCartItems.Contains(item.OfferKey)
&& item.CurrencyID == defaultCurrencyCode
&& item.Inventory > 0)
.ToList();
您的LINQ查询中似乎没有错误。请检查dataContext是否已初始化,以及与数据库的连接是否正常。