linq to SQL을 사용하여 한 번에 여러 행을 업데이트하는 방법은 무엇입니까?


91

표:

id     userid  friendid   name    status
1      1        2         venkat  false
2      1        3         sai     true
3      1        4         arun    false
4      1        5         arjun   false

사용자가 userid = 1, friendids = 2,4,5 status = true를 보낸 경우

위의 모든 friendids 상태를 업데이트하는 방법에 대한 쿼리를 알려주세요. [한 번에 2,3,4].?

감사

답변:


234

하나의 열을 업데이트하려면 다음과 같은 몇 가지 구문 옵션이 있습니다.

옵션 1

var ls=new int[]{2,3,4};
using (var db=new SomeDatabaseContext())
{
    var some= db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList();
    some.ForEach(a=>a.status=true);
    db.SubmitChanges();
}

옵션 2

using (var db=new SomeDatabaseContext())
{
     db.SomeTable
       .Where(x=>ls.Contains(x.friendid))
       .ToList()
       .ForEach(a=>a.status=true);

     db.SubmitChanges();
}

옵션 3

using (var db=new SomeDatabaseContext())
{
    foreach (var some in db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList())
    {
        some.status=true;
    }
    db.SubmitChanges();
}

최신 정보

주석에서 요청한대로 여러 열을 업데이트하는 방법을 보여주는 것이 합리적 일 수 있습니다. 따라서이 연습의 목적을 위해 statusat 1 을 업데이트하는 것이 아니라고 가정 해 보겠습니다 . 우리는 업데이트 할 namestatus를 Where friendid일치입니다. 이에 대한 몇 가지 구문 옵션은 다음과 같습니다.

옵션 1

var ls=new int[]{2,3,4};
var name="Foo";
using (var db=new SomeDatabaseContext())
{
    var some= db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList();
    some.ForEach(a=>
                    {
                        a.status=true;
                        a.name=name;
                    }
                );
    db.SubmitChanges();
}

옵션 2

using (var db=new SomeDatabaseContext())
{
    db.SomeTable
        .Where(x=>ls.Contains(x.friendid))
        .ToList()
        .ForEach(a=>
                    {
                        a.status=true;
                        a.name=name;
                    }
                );
    db.SubmitChanges();
}

옵션 3

using (var db=new SomeDatabaseContext())
{
    foreach (var some in db.SomeTable.Where(x=>ls.Contains(x.friendid)).ToList())
    {
        some.status=true;
        some.name=name;
    }
    db.SubmitChanges();
}

업데이트 2

대답에서 LINQ to SQL을 사용하고 있었고이 경우 데이터베이스에 커밋하는 방법은 다음과 같습니다.

db.SubmitChanges();

그러나 Entity Framework가 변경 사항을 커밋하려면 다음과 같습니다.

db.SaveChanges()

6
그리고 다수의 의견을 당신은 할 필요가 :records.ForEach(x=> { x.Deleted = true; x.DeletedByUserID = deletedByUserId; x.DeletedOn = DateTime.Now; });
JonH

2
그것은해야하지 db.SaveChanges()하지 db.SubmitChanges()?
bradlis7 2014

3
... 세 가지 옵션은 모두 동일합니다. 사실 처음 두 가지의 유일한 차이점은 하나는 변수를 사용하고 하나는 사용하지 않는다는 것입니다. 둘 다 가지고 있으면 소음이 증가합니다.
BlueRaja - 대니 Pflughoeft

3
없이 할 수 ToList()있습니까? 그것은 살인자
툴킷

2
ToList ()는 조건에 따라 데이터베이스에서 모든 레코드를 가져 오지 않습니까? 그게 맞다면 정말 나쁜 성능이 될 것입니다. 수백만 개의 레코드가 있다면이 기능을 작동시키기 위해 메모리에로드할까요? 내가 틀렸다면 수정 해주세요.
야곱

20

ToList()수락 된 답변과 같은 방법을 사용 하지 마십시오 !

SQL 프로파일 러를 실행하면서 ToList()함수가 데이터베이스에서 모든 레코드를 가져 오는 것을 확인하고 찾았 습니다. 정말 나쁜 성능입니다 !!

다음과 같이 순수 SQL 명령으로이 쿼리를 실행했을 것입니다.

string query = "Update YourTable Set ... Where ...";    
context.Database.ExecuteSqlCommandAsync(query, new SqlParameter("@ColumnY", value1), new SqlParameter("@ColumnZ", value2));

이것은 한 행도 선택하지 않고 원샷으로 업데이트를 수행합니다.


3

이것이 내가 한 일입니다.

EF :

using (var context = new SomeDBContext())
{
    foreach (var item in model.ShopItems)  // ShopItems is a posted list with values 
    {    
        var feature = context.Shop
                             .Where(h => h.ShopID == 123 && h.Type == item.Type).ToList();

        feature.ForEach(a => a.SortOrder = item.SortOrder);
    }

    context.SaveChanges();
}

희망은 누군가를 돕습니다.


매력처럼 작동합니다!
유 양 지앤

4
이것은 나쁘다. 레코드를 가져올 때마다 데이터베이스를 호출 feature하고 있으며 context.SaveChanges()내부에 추가 foreach해서는 안되며 foreach 루프 외부에 있어야합니다.
Jawand Singh 2017

1
SQL은 EF 코드와 동일하지 않습니다. SQL에서 모든 행에서 실행되고 테이블을 업데이트하는 것은 단지 하나의 명령입니다. EF 코드는 먼저 모든 행을 가져와 DB에서 변경된 행을 업데이트합니다. 즉, 업데이트 된 행이 1000 개이면 SQL 업데이트 1000 개를 실행합니다
Ashkan Sirous

1
@stom 여전히 동일하지 않습니다. :) context.SaveChanges (); 업데이트를 제출하기 만하면됩니다. SortOrder 조건이 아닌 ID를 사용하는 각각의 업데이트 명령은 여전히 ​​1000 개입니다.
Ashkan

2
@stom ExecuteSqlCommand는 이러한 목적으로 EF에 존재하지만 예쁘지 않다는 데 동의합니다. :) 어쨌든, 내 요점은 SQL 명령과 다른 EF-C # 코드를 작성하고 동일하다고 주장한다는 것입니다. :)
Ashkan Sirous
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.