使用Linq基于子对象特性最小值选择并更新
我有一个类型供应商,它有一个属性SupplierId和另一个属性NearestLocation,它是一个类型SupplierLocation,SupplierLocation由属性SupplierId和DistanceFromDevice组成使用Linq基于子对象特性最小值选择并更新,linq,c#-4.0,Linq,C# 4.0,我有一个类型供应商,它有一个属性SupplierId和另一个属性NearestLocation,它是一个类型SupplierLocation,SupplierLocation由属性SupplierId和DistanceFromDevice组成 class Supplier { public int SupplierId { get; set; } public SupplierLocation NearestLocation { get; set; } } class Supp
class Supplier
{
public int SupplierId { get; set; }
public SupplierLocation NearestLocation { get; set; }
}
class SupplierLocation
{
public int SupplierId { get; set; }
public decimal DistanceFromDevice { get; set; }
public double Longitude { get; set; }
public double Latitude {get; set;}
}
我有一份我所有供应商地点的清单,一个供应商可以有n个地点。我还计算了每个位置的DistanceFromDevice属性。
我有一个可以在供应商位置列表中找到其id的列表
我想使用linq做的是通过SupplierId将我的供应商加入到SupplierLocation,并使用该特定供应商的所有位置中距离设备值最小的位置填充supplier类的NearestLocation属性
希望这是有意义的。这可以使用linq完成吗
非常感谢。
Paul那么,您想在
供应商
上设置最近位置
,其中供应商ID
等于列表中的一个
假设您有一个名为“地点”的列表
,并且“currentSupplier”是您要分配以下位置的供应商
:
try
{
var minForSupplier = Locations.Where(x => x.SupplierId == currentSupplier.SupplierId).Min(x => x.DistanceFromDevice);
currentSupplier.NearestLocation = Locations.Where(x => x.SupplierId == currentSupplier.SupplierId && x.DistanceFromDevice == minForSupplier).Single();
}
catch(InvalidOperationException e)
{
// There is more than one SupplierLocation
}
下面是LINQPad中的一个工作示例
void Main()
{
var suppliers = new List<Supplier>
{
new Supplier() {SupplierId = 1},
new Supplier() {SupplierId = 2},
new Supplier() {SupplierId = 5}
};
var locations = new List<SupplierLocation>
{
new SupplierLocation {SupplierId = 1, DistanceFromDevice = 10, Latitude = 1, Longitude = 2},
new SupplierLocation {SupplierId = 1, DistanceFromDevice = 20, Latitude = 1, Longitude = 3},
new SupplierLocation {SupplierId = 1, DistanceFromDevice = 30, Latitude = 1, Longitude = 4},
new SupplierLocation {SupplierId = 1, DistanceFromDevice = 40, Latitude = 1, Longitude = 5},
new SupplierLocation {SupplierId = 2, DistanceFromDevice = 10, Latitude = 2, Longitude = 2},
new SupplierLocation {SupplierId = 2, DistanceFromDevice = 20, Latitude = 2, Longitude = 3},
new SupplierLocation {SupplierId = 3, DistanceFromDevice = 10, Latitude = 3, Longitude = 2}
};
var result = from s in suppliers
join l in locations on s.SupplierId equals l.SupplierId
into grp
where grp.Count() > 0
select new Supplier() { SupplierId = s.SupplierId, NearestLocation = grp.OrderBy (g => g.DistanceFromDevice).First()};
result.Dump();
}
class Supplier
{
public int SupplierId { get; set; }
public SupplierLocation NearestLocation{ get; set; }
}
class SupplierLocation
{
public int SupplierId { get ;set; }
public decimal DistanceFromDevice { get; set; }
public double Longitude { get; set; }
public double Latitude {get; set;}
}
void Main()
{
var供应商=新列表
{
新供应商(){SupplierId=1},
新供应商(){SupplierId=2},
新供应商(){SupplierId=5}
};
变量位置=新列表
{
新供应商位置{SupplierId=1,DistanceFromDevice=10,纬度=1,经度=2},
新供应商位置{SupplierId=1,DistanceFromDevice=20,纬度=1,经度=3},
新供应商位置{SupplierId=1,DistanceFromDevice=30,纬度=1,经度=4},
新供应商位置{SupplierId=1,DistanceFromDevice=40,纬度=1,经度=5},
新供应商位置{SupplierId=2,DistanceFromDevice=10,纬度=2,经度=2},
新供应商位置{SupplierId=2,DistanceFromDevice=20,纬度=2,经度=3},
新供应商位置{SupplierId=3,DistanceFromDevice=10,纬度=3,经度=2}
};
var结果=来自供应商的s
在s.SupplierId等于l.SupplierId的位置加入l
玻璃钢
其中grp.Count()>0
选择新供应商(){SupplierId=s.SupplierId,NearestLocation=grp.OrderBy(g=>g.DistanceFromDevice).First()};
result.Dump();
}
类供应商
{
public int SupplierId{get;set;}
公共供应商位置最接近位置{get;set;}
}
类供应商位置
{
public int SupplierId{get;set;}
公共十进制距离设备{get;set;}
公共双经度{get;set;}
公共双纬度{get;set;}
}
为什么特别想使用LINQ?除非我误解了你的问题,否则你不能循环查看你的供应商位置
列表,查找匹配的供应商ID
,并跟踪与设备的最低距离
。继续运行与ID和当前最小值匹配的列表Supplier
,最后,使用第一个列表(如果符合您的业务逻辑),或者如果不应超过1,则抛出和异常。感谢Vlad,这是一个诀窍-感谢您的时间。不过有一件小事-如果我没有一个特定供应商ID的任何位置-我会得到一个InvalidOperationException:序列不包含任何元素-我将尝试首先从供应商列表中删除所有这些供应商,然后进行连接-我想-除非有更好的处理方法this@Paul,我更新了我的代码,以处理您没有某个特定供应商的任何位置的情况。请看一看。非常感谢现在与count addedThanks完美配合,谢谢Ryan-此解决方案有助于满足位置可能不存在的事实,以及我每次都没有创建新供应商的事实-我正在用最近的位置更新现有供应商