Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 连接期间LINQ行内属性更新_C#_Linq - Fatal编程技术网

C# 连接期间LINQ行内属性更新

C# 连接期间LINQ行内属性更新,c#,linq,C#,Linq,这次讨论我有两个目标,A和B。我可以通过公共关系或外键连接这些对象(表)。我正在使用linq进行连接,我只想在结果集中返回ObjectA;但是,我希望在连接期间使用ObjectB中的数据更新ObejctA的属性,以便从LINQ查询中获得的ObjectAs与所选存储介质中的原始状态“略有”不同 这是我的查询,您可以看到,我只希望能够执行类似objectA.SomeProperty=objectB.AvalueIwant的操作 我知道我可以在我的select和spin-up新OBjectAs中做一个

这次讨论我有两个目标,A和B。我可以通过公共关系或外键连接这些对象(表)。我正在使用linq进行连接,我只想在结果集中返回ObjectA;但是,我希望在连接期间使用ObjectB中的数据更新ObejctA的属性,以便从LINQ查询中获得的ObjectAs与所选存储介质中的原始状态“略有”不同

这是我的查询,您可以看到,我只希望能够执行类似objectA.SomeProperty=objectB.AvalueIwant的操作

我知道我可以在我的select和spin-up新OBjectAs中做一个新的操作,但是如果可能的话,我希望避免这样做,而只是更新一个字段

return from objectA in GetObjectAs()
   join objectB in GetObjectBs()
           on objectA.Id equals objectB.AId
           // update object A with object B data before selecting it
   select objectA;

你能试试let语句吗?(不是在我的开发机器上亲自测试):

从单词“tables”中,听起来像是从数据库中获取这些数据。在这种情况下;不,你不能这样做。您可以做的最接近的操作是选择对象和额外的列,然后更新属性:

var qry = from objectA in GetObjectAs()
          join objectB in GetObjectBs()
             on objectA.Id equals objectB.AId
          select new { A = objectA,
              objectB.SomeProp, objectB.SomeOtherProp };

foreach(var item in qry) {
    item.A.SomeProp = item.SomeProp;
    item.A.SomeOtherProp = item.SomeOtherProp;
    // perhaps "yield return item.A;" here
}

如果您正在对对象执行LINQ,那么可能有一些黑客的方法可以使用流畅的API来实现—尽管不太漂亮。(类似编辑)

将更新方法添加到ClassA中

class ClassA {
  public ClassA UpdateWithB(ClassB objectB) {
    // Do the update
    return this;
  }
}
然后使用

return from objectA in GetObjectAs()
   join objectB in GetObjectBs()
           on objectA.Id equals objectB.AId
           // update object A with object B data before selecting it
   select objectA.UpdateWithB(objectB);
编辑

或者使用本地lambda函数,如:

Func<ClassA, ClassB, ClassA> f = ((a,b)=> { a.DoSomethingWithB(b); return a;});
return from objectA in GetObjectAs()
       join objectB in GetObjectBs()
       on objectA.Id equals objectB.AId
       select f(objectA , objectA );
Func f=((a,b)=>{a.DoSomethingWithB(b);返回a;});
从GetObjectAs()中的objectA返回
在GetObjectBs()中加入objectB
在objectA.Id上等于objectB.AId
选择f(objectA,objectA);

首先通过创建一个名为LinqExtensions的类来扩展Linq,使其具有Each选项

  public static class LinqExtensions
  {
    public static void Each<T>(this IEnumerable<T> source, Action<T> method)
    {
      foreach (var item in source)
      {
        method(item);
      }
    }
  }
参数传递示例:

objectA.Join(objectB,a=>a.Id,b=>b.Id,(a,b) => new {a,b.AValueIWant}).Each(o=>o.a.SomeMethod(o.AValueIWant));
这样做的好处是ObjectA和ObjectB不必是相同的类型。我用一个对象列表连接到一个字典(比如查找)来实现这一点。糟糕的是不清楚到底发生了什么。您最好跳过每个扩展,这样写

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);
}
但为了更清楚,我可能会这样做:

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;
}
您将需要在新对象中返回整个ObjectA,因为它将是只读的,并且唯一有效的原因是集合中的对象被引用,允许您对对象的属性进行更改


但最终,最明显的做法是跳过LINQ连接,在集合中循环查找匹配项,这将有助于将来的维护。LINQ非常棒,但就像当你有锤子的时候,它不会让一切都像钉子一样,当你有一个集合的时候,它并不意味着LINQ就是答案。

我在这里做一个左连接,所以我仍然拥有objectA的所有数据,即使objectB中的相应属性为空。因此,如果objectB中的相应属性为null,则必须定义在objectA中执行的操作。我一直使用这个语句连接两组数据。您不需要详尽地列出objectA中的所有属性及其映射方式,只需要列出要使用objectB更新的值。除非定义了到objectB的映射,否则objectA中预先存在的值是安全的

return from objectA in GetObjectAs()
   join objectB in GetObjectBs()
   on objectA.Id equals objectB.AId into combinedObj
   from subObject in combinedObj.DefaultIfEmpty()
   // update object A with object B data before selecting it
   select ((Func<objectAType>)(() =>
    {
        objectA.property = ((subObject == null) ? "Object B was null" : subObject.property);
        objectA.property = ((subObject == null) ? "Object B was null" : subObject.property);
        return objectA;
    }))()
从GetObjectAs()中的objectA返回
在GetObjectBs()中加入objectB
在objectA.Id上等于objectB.AId到combinedObj
来自CombinedObject.DefaultIfEmpty()中的子对象
//在选择对象A之前,使用对象B数据更新对象A
选择((Func)(()=>
{
objectA.property=((子对象==null)?“对象B为null”:子对象.property);
objectA.property=((子对象==null)?“对象B为null”:子对象.property);
返回对象a;
}))()

您可以通过以下方式进行尝试:

            var list1 = new List<ItemOne>
                        {
                            new ItemOne {IDItem = 1, OneProperty = "1"},
                            new ItemOne {IDItem = 2, OneProperty = null},
                            new ItemOne {IDItem = 3, OneProperty = "3"},
                            new ItemOne {IDItem = 4, OneProperty = "4"}
                        };
        var list2 = new List<ItemTwo>
                        {
                            new ItemTwo {IDItem = 2, TwoProperty = "2"},
                            new ItemTwo {IDItem = 3, TwoProperty = "3"},
                        };


        var query = list1.Join(list2, l1 => l1.IDItem, l2 => l2.IDItem, (l1, l2) =>
        {
            l1.OneProperty = l2.TwoProperty;
            return l1;
        });
var list1=新列表
{
新项目一{IDItem=1,OneProperty=“1”},
新项目一{IDItem=2,OneProperty=null},
新项目一{IDItem=3,OneProperty=“3”},
新项目一{IDItem=4,OneProperty=“4”}
};
var list2=新列表
{
新项目二{IDItem=2,TwoProperty=“2”},
新项目二{IDItem=3,TwoProperty=“3”},
};
var query=list1.Join(list2,l1=>l1.IDItem,l2=>l2.IDItem,(l1,l2)=>
{
l1.OneProperty=l2.TwoProperty;
返回l1;
});

不,你不能那样做;让我们只创建新变量-它不进行赋值。我正在从数据库中提取,但我不想将这些更改发布回数据库,只是允许这个“新”对象a携带一些不同的数据。这不适用于linq to sql,因为我有一个属性,该属性具有
[notmap]
属性
return from objectA in GetObjectAs()
   join objectB in GetObjectBs()
   on objectA.Id equals objectB.AId into combinedObj
   from subObject in combinedObj.DefaultIfEmpty()
   // update object A with object B data before selecting it
   select ((Func<objectAType>)(() =>
    {
        objectA.property = ((subObject == null) ? "Object B was null" : subObject.property);
        objectA.property = ((subObject == null) ? "Object B was null" : subObject.property);
        return objectA;
    }))()
            var list1 = new List<ItemOne>
                        {
                            new ItemOne {IDItem = 1, OneProperty = "1"},
                            new ItemOne {IDItem = 2, OneProperty = null},
                            new ItemOne {IDItem = 3, OneProperty = "3"},
                            new ItemOne {IDItem = 4, OneProperty = "4"}
                        };
        var list2 = new List<ItemTwo>
                        {
                            new ItemTwo {IDItem = 2, TwoProperty = "2"},
                            new ItemTwo {IDItem = 3, TwoProperty = "3"},
                        };


        var query = list1.Join(list2, l1 => l1.IDItem, l2 => l2.IDItem, (l1, l2) =>
        {
            l1.OneProperty = l2.TwoProperty;
            return l1;
        });