提前致谢。我可以在使用 var 时获得所需的输出,但我希望通过使用列表中的区别<> 来获得所需的输出。
InventoryDetails.cs
public class InventoryDetails
{
public int? PersonalInventoryGroupId { get; set; }
public int? PersonalInventoryBinId { get; set; }
}
InventoryController.cs
[HttpGet("GetInventory")]
public IActionResult GetInventory(int id)
{
//Below code will return distinct record
var inventory = (from i in _context.TempTbl
where i.TempId == id
select new
{
PersonalInventoryBinId = i.PersonalInventoryBinId,
PersonalInventoryGroupId = i.PersonalInventoryGroupId,
}).ToList().Distinct().ToList();
//Below code is not doing distinct
List<InventoryDetails> inventory = (from i in _context.TempTbl
where i.TempId == id
select new InventoryDetails
{
PersonalInventoryBinId = i.PersonalInventoryBinId,
PersonalInventoryGroupId = i.PersonalInventoryGroupId,
}).ToList().Distinct().ToList();
}
如果我使用var作为返回类型,那么我可以获得不同的记录。有人可以帮助它。
答案 0 :(得分:0)
请尝试这样做可能有所帮助。
IList<InventoryDetails> inventory = _context.InventoryDetails.Where(x=>x.TempId == id).GroupBy(p => new {p.PersonalInventoryGroupId, p.PersonalInventoryBinId } )
.Select(g => g.First())
.ToList();
答案 1 :(得分:0)
您需要覆盖Equals
和GetHashCode
。
首先,让我们看一下AnonymousType与InventoryDetails
var AnonymousTypeObj1 = new { PersonalInventoryGroupId = 1, PersonalInventoryBinId = 1 };
var AnonymousTypeObj2 = new { PersonalInventoryGroupId = 1, PersonalInventoryBinId = 1 };
Console.WriteLine(AnonymousTypeObj1.Equals(AnonymousTypeObj2)); // True
var InventoryDetailsObj1 = new InventoryDetails { PersonalInventoryBinId = 1, PersonalInventoryGroupId = 1 };
var InvertoryDetailsObj2 = new InventoryDetails { PersonalInventoryBinId = 1, PersonalInventoryGroupId = 1 };
Console.WriteLine(InventoryDetailsObj1.Equals(InvertoryDetailsObj2)); // False
您可以看到Equals的行为方式不同,使Distinct
的行为有所不同。您在问题中提到的问题不是var
,而是AnonoymizeType
要使Distinct
按预期工作,您需要覆盖Equals
和GetHashCode
public class InventoryDetails
{
public int? PersonalInventoryGroupId { get; set; }
public int? PersonalInventoryBinId { get; set; }
public override bool Equals(object obj)
{
if (obj == null) return false;
if (obj is InventoryDetails)
{
if (PersonalInventoryGroupId == (obj as InventoryDetails).PersonalInventoryGroupId
&& PersonalInventoryBinId == (obj as InventoryDetails).PersonalInventoryBinId)
return true;
}
return false;
}
public override int GetHashCode()
{
int hash = 17;
hash = hash * 23 + PersonalInventoryBinId.GetHashCode();
hash = hash * 23 + PersonalInventoryGroupId.GetHashCode();
return hash;
}
}
答案 2 :(得分:0)
另一种方法是
List<InventoryDetails> inventory = (from i in TempTbl
where i.TempId == id
select new InventoryDetails
{
PersonalInventoryBinId = i.PersonalInventoryBinId,
PersonalInventoryGroupId = i.PersonalInventoryGroupId,
}).AsQueryable().ToList().Distinct(new customComparer()).ToList();
public class customComparer:IEqualityComparer<InventoryDetails>
{
public bool Equals(InventoryDetails x, InventoryDetails y)
{
if (x.TempId == y.TempId && x.PersonalInventoryBinId == y.PersonalInventoryBinId
&& x.PersonalInventoryGroupId == y.PersonalInventoryGroupId)
{
return true;
}
return false;
}
public int GetHashCode(InventoryDetails obj)
{
return string.Concat(obj.PersonalInventoryBinId.ToString(),
obj.PersonalInventoryGroupId.ToString(),
obj.TempId.ToString()).GetHashCode();
}
}
答案 3 :(得分:0)
正如伊万的评论所说,在ToList
之前致电Distinct
,你会让生活变得困难。这可以防止SQL提供程序将Distinct
调用合并到生成的SQL语句中。但这留下了一个问题:导致差异的原因是什么?
第一个查询生成匿名类型实例。根据{{3}},默认情况下,匿名类型(在C#中)在属性和属性值相等时是相等的(结构相等)。相反,默认情况下,引用类型(如InventoryDetails
)在引用(例如内存地址)相等(引用相等或标识)时是相等的。通过覆盖Equals
和GetHashcode
方法可以使 相等,就像有些人建议的那样。
但如果删除第一个ToList()
var inventory = (from i in _context.TempTbl
where i.TempId == id
select new InventoryDetails
{
PersonalInventoryBinId = i.PersonalInventoryBinId,
PersonalInventoryGroupId = i.PersonalInventoryGroupId,
}).Distinct().ToList();
现在直到ToList()
的整个语句都是IQueryable
,可以转换为SQL。执行SQL并且数据库返回不同的原始记录结果集,EF从中生成InventoryDetails
个对象。 C#运行时代码甚至从未意识到重复!