Mikroskop.Çerçeve çalışması hakkı.DbUpdateConcurrencyException: 'Veritabanı işleminin 1 satır(lar) ı etkilemesi bekleniyor, ancak aslında 2 satır(lar)ı etkiledi

0

Soru

Tabloyu aynı değerle (karNumber) güncellemeye çalıştığımda bu hatayı aldım, koşulum gerçek dönüş tarihi alanının null olduğu yeri güncellemektir.

Bazı nedenlerden dolayı sorgu 2 satır döndürüyor gibi görünüyor, ancak aslında sadece bir tane var. EF kullanıyorum. Bu işlev:

hata-yazdırma ekranı

   public void updateStatus(int carNumber1, string acctualDate1)
    {
        DateTime accReturn = DateTime.Parse(acctualDate1);

        var orderCar1 =  db.CarRentalFields.FirstOrDefault(carNum =>
        (carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null));

            orderCar1.ActualReturnDate = accReturn  ;
             
                db.SaveChanges();

Db çalışırken hata yükseltin.saveChanges()

db'den tablo, araç numarası 1000-baskı ekranı

Model yapımcısı.Varlık resmi

lütfen bu sorunu nasıl çözebileceğimi bana bildirin.

c# entity-framework linq sql-server
2021-11-23 20:34:34
2
0

car_rental_fields tablosuna yeni bir sütun ekleyerek sorun çözüldü, Kimliği içeren kimlik sütunu. buradan ve web'den anladığım kadarıyla, karmaşık pk ile ilgili bir sorun var. çözümümde kimlik birincil anahtar değil, ancak lınq'in doğru sütunu güncellemesi için mantık oluşturuyor. bu konuyla ilgilenen herkese teşekkürler.

2021-11-26 20:37:27
0

Bu hata, EF varlığınız için pk'yi çözemediğinde oluşur. Çoğu durumda basit varlıklar için EF kuralları pk'yi çalıştırabilir, ancak sizin durumunuzda bileşik bir anahtar kullanıyorsunuz, bu nedenle bunun yapılandırılması gerekiyor. Varlıklarınızı nasıl haritaladığınıza bağlı olarak bunu şu adresten yapabilirsiniz::

  • bir EDMX
  • DbContext içinde.Onmodel Oluşturma
  • bir kullanarak EntityTypeConfiguration bildiri
  • varlığın kendi içindeki öznitelikleri kullanma

Varlıklarınızın nasıl yapılandırıldığını bilmediğimizden, varlığınızdaki öznitelik yaklaşımını test olarak kullanarak bunu neden olarak doğrulayabilirsiniz. Bir EDMX kullanıyorsanız, varlık sınıfları oluşturulur, böylece bunu EDMX içindeki yapılandırmayla değiştirmek istersiniz. (Sana gerçekten yardım edemem çünkü lanet şeyleri kullanmıyorum: D )

Muhtemelen böyle bir şeye sahip olacaksınız:

public class CarRentalFields
{
    [Column("start_day")]
    public DateTime StartDay { get; set; }
    [Column("return_date")]
    public DateTime ReturnDate { get; set; }
    [Column("user_id")]
    public int UserId { get; set; }
    [Column("car_number")]
    public DateTime CarNumber { get; set; }
    
    // ... more columns...
}

Hatta bir tane bile olabilir [Key] CarNumber gibi bu alanlardan birinde öznitelik. Varlıkta eşlenen bir PK varsa, sorun, satırı benzersiz olarak tanımlayacak kadar spesifik olmamasıdır. EF bir varlığı güncelleştirmeye gittiğinde, denetliyor ve tablodaki yalnızca bir satırı güncelleştirmeyi bekliyor. Birden fazla satırın etkileneceğini buluyor, bu yüzden başarısız oluyor.

İçin öznitelikleri ekleme [Key] sütun sırası ile bileşik anahtar olarak tanınır.

public class CarRentalFields
{
    [Key, Column(Name="start_day", Order=1)]
    public DateTime StartDay { get; set; }
    [Key, Column(Name="return_date", Order=2)]
    public DateTime ReturnDate { get; set; }
    [Key, Column(Name="user_id", Order=3)]
    public int UserId { get; set; }
    [Key, Column(Name="car_number", Order=4)]
    public DateTime CarNumber { get; set; }
    
    // ... more columns...
}

Bu 4 sütunun tabloda benzersiz bir kısıtlama olması garanti edilirse, EF, UPDATE SQL deyimini oluştururken yalnızca bir satır güncellendiğinde tatmin olur.

Bu işe yararsa ve bir EDMX kullanıyorsanız, bu varlık sınıfı yeniden oluşturulabileceğinden, ek özniteliklerinizi kaybederek uygun değişiklikleri yapmak için EDMX eşlemenizi gözden geçirmeniz ve değiştirmeniz gerekeceğini tekrar unutmayın. (Bir edmx'ten oluşturulan varlık sınıflarının, oluşturulan bir sınıf olduğu konusunda sizi uyaran bir yorum başlığına sahip olduğuna inanıyorum, bu nedenle dikkat edilmesi gereken bir göstergedir.)

Güncelleme: Bu konudaki birincil şüphelim, tablonun aslında farklı bir PK kombinasyonu çalıştıran veya bu alanların niteliği göz önüne alındığında daha büyük olasılıkla PK olmayan eşleşen bir PK tanımına sahip olmaması olacaktır. EF, PK tanımlı olmayan tablolarda çalışabilir, ancak kayıtların benzersiz olarak tanımlanabilmesini sağlayan bir Anahtar tanımı gerektirir. Gördüğünüz hata, bu anahtar tanımı yeterince benzersiz olmadığında gerçekleşir. (Yani, araç 1'i güncelliyorsanız ve sahip olduğunuz satırı seçiyorsanız: car_number = 1, start_day = 2021-11-21, return_day = 2021-11-22, user_id = 0 Sorun, birden fazla satırın db'de bu kombinasyona sahip olmasıdır. Denetlediğiniz db'nin birden fazla eşleşen satırı yoksa, uygulamanız neredeyse kesinlikle denetlediğinizden farklı bir veritabanına işaret ediyor demektir.

Bunu doğrulamak için yapabileceğiniz şeyler:

  1. çalışma zamanı bağlantı dizesini alın ve denetlediğiniz DB ile eşleşip eşleşmediğine bakın:

Sorgunuzu çalıştırmadan önce aşağıdakileri ekleyin:

// EF6
var connectionString = db.Database.Connection.ConnectionString;
// EF Core 5
var connectionString = db.Database.GetConnectionString();
  1. Gerçekten sorguladığınız verilere bir göz atın:

.

var cars =  db.CarRentalFields.Where(carNum =>
    (carNum.CarNumber == carNumber1 && carNum.ActualReturnDate == null)).ToList();

Bu sorgu yalnızca 1 kaydı döndürebilirken, sorunun nedeni bu değildir. İstediğiniz şey, bu kayıt için CarNumber, StartDate, ReturnDate ve userıd'dir:

var car =  db.CarRentalFields
    .Where(carNum => carNum.CarNumber == carNumber1 
        && carNum.ActualReturnDate == null)
    .Select(x => new 
    {
        x.CarNumber,
        x.StartDay,
        x.ReturnDate,
        x.UserId
    }).Single(); // Expect our 1 record here...
var cars = db.CarRentalFields
    .Where(x => x.CarNumber == car.CarNumber
        && x.StartDay == car.StartDay
        && x.ReturnDate == car.ReturnDate
        && x.UserId == car.UserId)
    .ToList(); // Get rows that match our returned Key fields.

Bu sorgular, güncellemek istediğiniz araç kaydının varsayılan PK değerlerini seçer, ardından beklenen Anahtar alanlarla eşleşen kayıtlar için araçlarda arama yapar. Param, üst sorgu 1 kayıt döndürürken, alt sorgu iki satır döndürür, yani yalnızca 1 kayıt #null ActualReturnDate değerine sahipken, Anahtarınız bu tablonun içeriği için yeterince benzersiz değildir.

2021-11-26 22:57:48

contex kullanıyorum, model oluşturucunun baskı ekranımı gördünüz mü?
elirans

Evet, tamam, Dbcontext'in OnModelCreating Modelbuilder'ını kullanıyor, bu yüzden Anahtar tanımlanıyor. Kontrol edilecek bir sonraki şey, bu sütunların karşılık gelen veritabanınızdaki PK /w benzersiz kısıtlamasıyla eşleşip eşleşmediği olacaktır. Değilse, bu anahtarın genişletilmesi gerekebilir. Bileşik anahtarlardan mümkün olduğunca kaçınılmalıdır, çünkü ilişki kurmayı çok daha fazla iş haline getirirler. Önerilen update deyimini yakalamak için bir profil oluşturucu da kullanabilir, ardından hangi satırların döndürüldüğünü görmek için bunu basit bir seçime dönüştürebilirsiniz. Bazı nedenlerden dolayı birden fazla satır geri geliyor.
Steve Py

Kontrol edilmesi gereken başka bir şey, çalışma zamanında uygulamanın kontrol ettiğiniz veritabanıyla aynı veritabanına çarpıp çarpmadığıdır. Denetlediğiniz veriler, DB bu sütunlar üzerinde benzersiz bir kısıtlama uygulamıyorsa, ancak çalışma zamanında işaret edilen veritabanının yinelenen satırları varsa, yeterince benzersiz görünebilir.
Steve Py

çözümünüzü kullanarak aynı hata oluştu, işlevimi de değiştirmem gerekiyor muydu? @ Steve Py
elirans

Oluşturulan sql'i yakalayın ve veritabanında çalıştırın. Genellikle bunun için bir Profil Oluşturucu kullanırım, bu nedenle SQL Server ve SSMS için Tools\SQL Profiler altında. Bunu db'nize karşı çalıştırın, ardından sorgunuzu yürütün. Uygulamanızda kaydetme değişikliklerinden hemen önce bir kesme noktası kullanabilir, ardından önceki gürültüyü temizlemek ve UPDATE deyiminizi bulmak için devam etmeden önce profiler çıktısını temizleyebilirsiniz.
Steve Py

Ayrıca, tablonuz için tablo tasarımcısı çıktısını gönderebilir misiniz? Tabloda bu 4 sütunla gerçek bir PK kümesi var mı?
Steve Py

Yukarıdaki cevaba, bağlantı dizesini iki kez kontrol etmenin yanı sıra verilerde yinelenen anahtar değerleri olup olmadığını doğrulamak için adımlar eklemek için ekledim.
Steve Py

Çözümünü denedim. ilk olarak, arabalardaki bazı '=' leri özlüyormuşsunuz gibi görünüyor. ikinci şey-güncellemeyi yapmaya çalıştığımda: arabalar.ActualReturnDate = acctualDate1; cs1061 hatası aldım.
elirans

Diğer dillerde

Bu sayfa diğer dillerde

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................