2013-04-25 79 views
2

我有了一个属性供应商ID和其他属性NearestLocation这是一种SupplierLocation的类型供应商属性的最小值时,SupplierLocation由性供应商ID和DistanceFromDevice选择和基于子更新对象使用LINQ

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;} 
} 

我有一个供应商可以有多个位置的我所有供应商的列表。我还计算了每个位置的DistanceFromDevice属性。 我有一个列表,其ID可以在SupplierLocations列表中找到。

我想要使用linq的方法是将我的供应商加入到SupplierId的SupplierLocation中,并填入供应商类的NearestLocation属性,该位置的DistanceFromDevice值为该特定供应商的所有位置的最小值。

希望这是有道理的。这可以使用linq完成。

非常感谢提前。 保罗

+0

为什么你特别想使用LINQ吗?除非我误解了你的问题,否则你是否可以遍历你的'SupplierLocation'列表,查找匹配的'SupplierId'并跟踪最低的'DistanceFromDevice'。保持符合ID和当前最小值的运行列表“供应商”,并在最后使用第一个(如果这符合您的业务逻辑)或抛出异常,如果不应超过1个。 – Thelonias 2013-04-25 19:29:09

回答

1

这里是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;} 
} 
+0

感谢Vlad这样做诀窍 - 感谢您的时间。尽管一件小事 - 如果我没有一个特定供应商的任何位置Id - 我得到一个InvalidOperationException:序列不包含任何元素, - 我会尝试先将所有这些供应商从供应商列表中删除,然后再进行连接 - 我猜 - 除非有更好的方法来处理这个 – Paul 2013-04-26 07:28:38

+0

@Paul,我更新了我的代码以处理您没有任何特定供应商的任何位置的情况。请看一下。 – 2013-04-26 12:27:18

+0

非常感谢,这与现在的计数完美结合 – Paul 2013-04-26 14:12:58

1

所以,你要设置NearestLocationSupplier其中SupplierId等于一个在List<SupplierLocation>

假设你有一个List<SupplierLocation>名为“位置”和“currentSupplier”是你要分配的NearestLocation的Supplier

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 
} 
+0

谢谢对于这一点瑞安 - 这个解决方案有助于迎合地点可能不存在的事实以及我并未每次创建新供应商这一事实 - 我正在更新现有供应商并与最近的地点联系 – Paul 2013-04-26 08:16:50