0

このクエリをLinqの方法で実行する方法を知りたいのですが。

UPDATE orders SET shipDate = '6/15/2012' WHERE orderId IN ('123123','4986948','23947439')

私のコード、

[HttpGet]
public void test()
{
    EFOrdersRepository ordersRepository = new EFOrdersRepository();
    var query = ordersRepository.Orders;

    // How to run this query in LINQ
    // Query : UPDATE orders SET shipDate = '6/15/2012' WHERE orderId IN ('123123','4986948','23947439')
}

EFOrdersRepository.cs

public class EFOrdersRepository
{
    private EFMysqlContext context = new EFMysqlContext();

    public IQueryable<Order> Orders
    {
        get { return context.orders; }
    }
}

EFMysqlContext.cs

class EFMysqlContext : DbContext
{
     public DbSet<Order> orders { get; set; }
}
4

4 に答える 4

2

実際、次のコードを確認するのは非常に簡単です

EFOrdersRepository db = new EFOrdersRepository();
int[] ids= new string[] { "123123", "4986948", "23947439"};
//this linq give's the orders with the numbers
List<Order> orders = db.Order().ToList()
                        .Where( x => ids.Contains(x.orderId.Contains));

foreach(var order in orders)
{
    order.ShipDate = '06/15/2012';
    db.Entry(usuario).State = EntityState.Modified;
}

  db.SaveChanges();
于 2012-06-15T18:24:34.830 に答える
0

このようなものが機能するはずです(疑似コードを先に警告します!!)

編集私は注文をよりよく取得するホルヘの方法を使用するのが好きです(containsを使用)が、これを別の選択肢としてここに残します。ただし、コードサンプルの下のステートメントは引き続き当てはまります。

[HttpGet]
    public void test()
    {
        EFOrdersRepository ordersRepository = new EFOrdersRepository();
        var query = ordersRepository.Orders.Where(x=>x.orderId == '123123' || 
x.orderId == '4986948' || x.orderId = '23947439').ToList();
            foreach(var order in query){
               var localOrder = order; 
               order.ShipDate = '06/15/2012';
            }
            ordersRepository.SaveChanges();
        }

基本的に、LINQは「一括更新」をうまく実行しません。注文をフェッチしてループするか、IDの配列を取得してその方法で一括更新できるストアドプロシージャを作成する必要があります。一度に数回しか実行しない場合は、上記で問題なく動作します。更新する必要のある注文が大量にある場合、ORMはおそらく最良の選択ではありません。他の誰かがより良いアプローチを持っているかどうかを確認することを楽しみにしています。

免責事項:ラインは、変更されたクロージャの問題var localOrder = orderがないことを確認することです。また、ReSharperやその他のツールでは、上記の記述方法がそれほど冗長ではない場合があります。

于 2012-06-15T18:23:46.473 に答える
0

注:最後にSaveChangesあなたから電話する必要がありますDBContext

短い答え:

var f = new[] { 123123, 4986948, 23947439 };
var matchingOrders = orders.Where(x => f.Contains(x.ID)).ToList();
matchingOrders.ForEach(x => x.ShipDate = newDate);

完全なテスト:

    // new date value
    var newDate = new DateTime(2012, 6, 15);
    // id's
    var f = new[] { 123123, 4986948, 23947439 };
    // simpulating the orders from the db
    var orders = Builder<Order2>.CreateListOfSize(10).Build().ToList();
    orders.Add(new Order2 { ID = 123123 });
    orders.Add(new Order2 { ID = 4986948 });
    orders.Add(new Order2 { ID = 23947439 });

    // selecting only the matching orders
    var matchingOrders = orders.Where(x => f.Contains(x.ID)).ToList();

    matchingOrders.ForEach(x => Console.WriteLine("ID: " +  x.ID + " Date: " + x.ShipDate.ToShortDateString()));
    // setting the new value to all the results
    matchingOrders.ForEach(x => x.ShipDate = newDate);
    matchingOrders.ForEach(x => Console.WriteLine("ID: " + x.ID + " Date: " + x.ShipDate.ToShortDateString()));

出力:

ID: 123123 Date: 1/1/0001
ID: 4986948 Date: 1/1/0001
ID: 23947439 Date: 1/1/0001
ID: 123123 Date: 6/15/2012
ID: 4986948 Date: 6/15/2012
ID: 23947439 Date: 6/15/2012
于 2012-06-15T18:40:39.067 に答える
0

ORMでは、最初にレコードをフェッチしてからレコードに変更を加えてから、保存し直す必要があります。これを行うには、次のようにUpdateOrderメソッドをリポジトリに追加します

public bool UpdateOrder(Order order)
{
   int result=false;
   int n=0;
   context.Orders.Attach(order);
   context.Entry(order).State=EntityState.Modified;
   try
   {
      n=context.SaveChanges();
      result=true;
   }
   catch (DbUpdateConcurrencyException ex)
   {
      ex.Entries.Single().Reload();
      n= context.SaveChanges();        
      result= true;
   }
  catch (Exception ex2) 
  {
    //log error or propogate to parent 
  }
  return result;
}

そして、私はこのように私のアクションメソッドからそれを呼び出します

int orderId=123232;
var orders=ordersRepository.Orders.Where(x=> x.orderId.Contains(orderId)).ToList();
if(orders!=null)
{
   foreach(var order in orders)
   {
     order.ShipDate=DateTime.Parse('12/12/2012);
     var result= ordersRepository.UpdateOrder();     
   }
}

このアプローチでは、多数のレコードを更新する必要がある場合、その数の更新ステートメントをデータベースに対して実行します。Database.SqlQueryこの特定のケースでは、メソッドを使用して1つのクエリのみでRawSQLステートメントを実行したいと思います。

string yourQry="UPDATE orders SET shipDate = '6/15/2012' 
                     WHERE orderId IN ('123123','4986948','23947439')";
var reslt=context.Database.SqlQuery<int>(yourQry);
于 2012-06-15T18:28:37.887 に答える