LINQ In Line Property Update During Join

后端 未结 6 1421
难免孤独
难免孤独 2021-02-05 11:55

I have two obects, A & B for this discussion. I can join these objects (tables) via a common relationship or foreign key. I am using linq to do this join and I only want t

6条回答
  •  余生分开走
    2021-02-05 12:26

    First extend Linq to have an Each option by creating a class called LinqExtensions.

      public static class LinqExtensions
      {
        public static void Each(this IEnumerable source, Action method)
        {
          foreach (var item in source)
          {
            method(item);
          }
        }
      }
    

    Then you can use Join to return a list of new objects that contain the original objects with it's appropriate value. The Each will iterate over them allowing you to either assign or pass the values as parameters to each object.

    Assignment example:

    objectA.Join(objectB,a=>a.Id,b=>b.Id,(a,b) => new {a,b.AValueIWant}).Each(o=>o.a.SomeProperty=o.AValueIWant);
    

    Parameter passing example:

    objectA.Join(objectB,a=>a.Id,b=>b.Id,(a,b) => new {a,b.AValueIWant}).Each(o=>o.a.SomeMethod(o.AValueIWant));
    

    The nice thing about this is that ObjectA and ObjectB do not have to be the same type. I have done this with a list of objects joined to a Dictionary (like a lookup). Bad thing is it isn't clear what is going on. You would be better to skip the Each extention and write it like this.

    foreach(var change in objectA.Join(objectB,a=>a.Id,b=>b.Id,(a,b) => new {a,b.AValueIWant}))
    {
      change.a.SomeProperty = change.AValueIWant;
      change.a.SomeMethod(change.AValueIWant);
    }
    

    But for more clarity I would probably do this:

    foreach(var update in objectA.Join(objectB,objectA=>objectA.Id,objectB=>objectB.Id,(objectA,objectB) => new {objectA, Value = objectB.AValueIWant}))
    {
      update.objectA.SomeProperty = update.Value;
    }
    

    You will need to return the whole ObjectA in your new object, because it will be readonly and the only reason this works is because the objects in a collection are referenced allowing you to make your changes to properties on the objects.

    But in the end it would be clearest to skip the LINQ join all together and just loop through the collections and look for matches, this will help with future maintenence. LINQ is awesome but just like when you have a hammer it doesn't make everything a nail, when you have a collection it doesn't mean LINQ is the answer.

提交回复
热议问题