这是一种优雅的方式来检查是否存在具有相同子项的物品
本文关键字:存在 是否 检查 一种 方式 | 更新日期: 2023-09-27 18:27:07
我有这个项目:
public partial class PACK
{
public int PACK_IDE { get; set; }
public string PACK_DESCR { get; set; }
public Nullable<System.DateTime> PACK_DATE_CREATED { get; set; }
public Nullable<System.DateTime> PACK_DATE_MODIFIED { get; set; }
public Nullable<System.DateTime> PACK_DATE_LAST_CALC { get; set; }
public decimal PACK_COST { get; set; }
public int PACK_QTY_POSS { get; set; }
public string PACK_NOTE { get; set; }
public int PACK_QTY_SOLD { get; set; }
public decimal PACK_AVRG_SELL_PRICE { get; set; }
public Nullable<int> PACK_DESTINATION { get; set; }
public virtual ICollection<INVENTORY_PACK> INVENTORY_PACK { get; set; }
}
如你所见,它包含一个库存包列表,形状如下:
public partial class INVENTORY_PACK
{
public int INVENT_PACK_IDE { get; set; }
public int INVENT_IDE { get; set; }
public int PACK_IDE { get; set; }
public int QTY { get; set; }
public virtual INVENTORY INVENTORY { get; set; }
public virtual PACK PACK { get; set; }
}
最后,库存项目,它有两个重要的字段,现在很重要:
public partial class INVENTORY
{
public int INVENT_IDE { get; set; }
public Nullable<int> CARD_IDE { get; set; }
public Nullable<int> INVENT_NB_IN_STOCK { get; set; }
public Nullable<int> INVENT_NB_QT_SOLD { get; set; }
public string INVENT_ITEM_STATE { get; set; }
public virtual CARD CARD { get; set; }
public virtual ICollection<INVENTORY_PACK> INVENTORY_PACK { get; set; }
}
当我实际保存或创建一个新包时,我需要找到一种方法来检查实际包是否存在,该包基于INVENT_ITEM_STATE
和CARD_IDE
以及INVENTORY_PACK
中的QTY
具有完全相同的库存项。如果这三个值相同,那么我们可以考虑生同样的孩子。我基本上需要搜索任何包(使用Linq或任何Linq-to-Sql调用),其中的子级与我现在拥有的相同,但我真的不知道如何做到这一点,除了大量令人震惊的for/foreach循环。
编辑
根据要求,这里有一个我一直在努力做的例子
internal void CreatePack(PackInfo _pack)
{
using (TransactionScope scope = TransactionUtils.CreateTransactionScope())
{
try
{
var packQry = from pa in mDb.PACK
select pa;
if (!packQry.Any())
{
PACK packToAdd = DataConverter.PackInfoToPACKData(_pack);
mDb.PACK.Add(packToAdd);
mDb.SaveChanges();
int packID = mDb.PACK.Max(_x => _x.PACK_IDE);
foreach (INVENTORY_PACK inventoryPack in packToAdd.INVENTORY_PACK)
{
inventoryPack.PACK_IDE = packID;
mDb.SaveChanges();
}
}
else
{
List<PACK> listPacks = new List<PACK>();
foreach (var inventoryPackInfo in _pack.mListInventoryPackInPack)
{
packQry = from pa in mDb.PACK
where pa.INVENTORY_PACK.Any(_item =>
_item.INVENTORY.INVENT_IDE ==
inventoryPackInfo.mInventoryItem.mInventoryID)
where pa.INVENTORY_PACK.Any(
_item =>
_item.INVENTORY.INVENT_ITEM_STATE ==
inventoryPackInfo.mInventoryItem.mItemState)
where pa.INVENTORY_PACK.Any(_item => _item.QTY == inventoryPackInfo.mQuantity)
select pa;
if (packQry.Any())
{
listPacks.AddRange(packQry);
}
}
if (_pack.mListInventoryPackInPack.Count == 1)
{
}
IDictionary<PACK, int> counts = new Dictionary<PACK, int>();
foreach (var pack in listPacks)
{
if (!counts.ContainsKey(pack))
{
counts.Add(pack, 1);
}
else
{
counts[pack]++;
}
}
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
scope.Complete();
}
}
示例
我想我需要澄清我的需要。下面是一个例子。
假设我有1个包含2个INVENTORY_PACK
的PACK
:1是INVENTORY
项,其中INVENT_IDE
1234,CARD_IDE
4321,QTY
是1,而INVENT_ITEM_STATE
是PERFECT
。第二个对象是INVENT_IDE
4567、CARD_IDE
7654、QTY
是2和INVENT_ITEM_STATE
PERFECT
。
我需要检查包,看看是否已经有一个包包含,确切地说在所选参数中有两个项目。所以有很多可能性:
- 如果我们有另一个现有的
PACK
,它具有相同的项目和相同数量的项目(在本例中为2)、数量和IDS,则我们有一个完全匹配,并且我们认为PACK
已经存在 - 如果有一个
PACK
包含相同的项目,但有另一个项目(本例为3个或更多项目),是否认为是另一个包;那么我们就没有对手了 - 如果任何包裹只有其中一项,则我们没有匹配项
如果我理解得很好,您可以执行以下操作:
实现两个EqualityComparer(可以在您的业务层中实现,因为它只是业务逻辑)
class PACK_Comparer : EqualityComparer<PACK>
{
public override bool Equals(PACK p1, PACK p2)
{
// Two PACK are Equals if their INVENTORYs contains the same INVENTORY items
return (p1.INVENTORY_PACK.Count() == p2.INVENTORY_PACK.Count()
&& p1.INVENTORY_PACK.Intersect(p2.INVENTORY_PACK, new INVENTORY_PACK_Comparer()).Count() == p1.INVENTORY_PACK.Count());
}
public override int GetHashCode(PACK p)
{
// Ensure that if the Equals method returns true for two PACK p1 and p2
// then the value returned by the GetHashCode method for p1 must equal the value returned for p2
INVENTORY_PACK_Comparer comp = new INVENTORY_PACK_Comparer();
int hCode = 0;
foreach (var i in p.INVENTORY_PACK)
hCode ^= comp.GetHashCode(i);
return hCode.GetHashCode();
}
}
class INVENTORY_PACK_Comparer : EqualityComparer<INVENTORY_PACK>
{
public override bool Equals(INVENTORY_PACK i1, INVENTORY_PACK i2)
{
// Two INVENTORY_PACK are Equals if their INVENT_ITEM_STATE, CARD_IDE and QTY are Equals
return (i1.INVENTORY.INVENT_ITEM_STATE == i2.INVENTORY.INVENT_ITEM_STATE
&& i1.INVENTORY.CARD_IDE == i2.INVENTORY.CARD_IDE
&& i1.QTY == i2.QTY);
}
public override int GetHashCode(INVENTORY_PACK i)
{
// Ensure that if the Equals method returns true for two INVENTORY_PACK i1 and i2
// then the value returned by the GetHashCode method for i1 must equal the value returned for i2
int hCode = i.INVENTORY.INVENT_ITEM_STATE.GetHashCode()
^ i.INVENTORY.CARD_IDE.GetHashCode()
^ i.QTY.GetHashCode();
return hCode.GetHashCode();
}
}
然后检查是否存在与一样短的相同PACK
bool exist = mDb.PACK.Contains(_pack, new PACK_Comparer());
如果你想获取mDb:中已经存在的实际PACK
PACK_Comparer comp = new PACK_Comparer();
PACK existingPack = mDb.PACK.FirstOrDefault(p => comp.Equals(p, _pack));
请注意,我删除了"测试为空"的内容以使其更简单。您需要自己实现这一点。
谨致问候,Gerard
这可能就是您想要的
int count = (from p in _pack.INVENTORY_PACK
where pack.INVENTORY.INVENT_ITEM_STATE == p.INVENTORY.INVENT_ITEM_STATE
select p).Count();
检查if(pack.QTY == count)
之后