Entity Framework: “Güncelleme, ekleme veya silme ifadesini depolamak beklenmedik sayıda satırı (0) etkiledi.” [kapalı]


324

Bir ızgara denetimi doldurmak için Entity Framework kullanıyorum. Bazen güncelleme yaptığımda aşağıdaki hatayı alıyorum:

Güncelleme, ekleme veya silme ifadesini saklamak beklenmedik sayıda satırı etkiledi (0). Varlıklar yüklendiği için varlıklar değiştirilmiş veya silinmiş olabilir. ObjectStateManager girişlerini yenileyin.

Bunu nasıl çoğaltacağımı anlayamıyorum. Ancak güncellemeleri ne kadar yakın yaptığımla ilgili bir şey olabilir. Bunu gören var mı veya hata mesajının ne anlama geldiğini bilen var mı?

Düzenleme: Ne yazık ki ben artık bu projeden uzaklaştı ve sonunda bir çözüm buldum, başka bir geliştirici onu düzelttiyse ya da çevresinde çalıştım, hatırlamıyorum çünkü burada yaşıyorum sorunu yeniden oluşturmak için özgür değilim. Bu yüzden cevap kabul edemem.


Bu hatayı geri okunamayan bir duruma (izin verilen bir BLOCK yüklemiyle özel bir FİLTRE yüklemesi) izin veren bir SQL Server Satır Düzeyi Güvenlik ilkesinin sunulmasıyla bu hatayı aldım . EntityFramework, güncellemeden sonra güncellenen satırın tekrar okunmasını gerektirir, aksi takdirde bunun bir eşzamanlılık hatası olduğunu varsayar (en azından iyimser eşzamanlılık kullanılırken).
xr280xr

Sorun, DBContext stackoverflow.com/questions/49154250/… için yanlış kapsam belirleme olabilir (bu örnek ASPNET Identity içindir, ancak herhangi bir bağlam için geçerlidir)
Simon_Weaver

Bu hatanın bağlamından bağımsız olarak, bağlamın somutlaştırıldığı yere bir kesme noktası koymak iyi bir fikirdir. Bir web sayfası yüklediğinizde bir kez örneklenmesini bekliyordunuz, ancak bu kesme noktasına 5 kez çarpıyor mu? O zaman muhtemelen bir yarış durumunuz var. Bak Request.Uriasıl isteği URL'sini görmek için. Benim durumumda, siteme isabet eden ve gereksiz yere DB'den yükleme (ve bazen de güncelleme) bazı izleme mantığı vardı. O zaman hata ayıkladığım gerçek sayfanın verileri aptal bir izleme kodu mantığı tarafından bastırılmıştı.
Simon_Weaver

Görünümde @ Html.AntiForgeryToken () ekle
Vikas Sharma

Yanıtlar:


199

Bu, iyimser eşzamanlılık adı verilen bir özelliğin yan etkisidir.

Entity Framework'te nasıl açılıp kapatılacağından% 100 emin değilim ama temel olarak size söylediği şey, verileri veritabanından aldığınız ve değişikliklerinizi kaydettiğinizde başka birinin verileri değiştirdiği (yani, kaydetmek için 0 satır aslında güncellendi). SQL terimlerinde, updatesorgularının whereyan tümcesi satırdaki her alanın orijinal değerini içerir ve 0 satır etkilenirse bir şeyin yanlış gittiğini bilir.

Bunun arkasındaki fikir, uygulamanızın bilmediği bir değişikliğin üzerine yazmamanızdır - temelde .NET tarafından tüm güncellemelerinize atılan küçük bir güvenlik önlemidir.

Tutarlıysa, olasılıklar kendi mantığınız içinde gerçekleşiyor (EG: Verileri aslında seçim ve güncelleme arasındaki başka bir yöntemle kendiniz güncelliyorsunuz), ancak bu sadece iki uygulama arasındaki bir yarış durumu olabilir.


34
Bu, tek kullanıcılı bir ortamda (dev makinemde) oluyor, bu yüzden bunun bir yarış durumu olabileceğini düşünmüyorum. EntityDataSource ile özel bir ızgara denetimine bağlanıyor, bu yüzden tam olarak sahnelerin arkasında neler olduğundan emin değilim, ama tabloları değiştiren kendi herhangi bir ekstra kodu yok. Bu eşzamanlılık ayarını değiştirmenin bir yolu var mı?
strongopinions

3
Varlık modelinizde sütun başına temelinde yapabileceğinizi düşünüyorum (Özellikler penceresinde), ama şey sadece hatayı görmenizi engelleyecek ve hala hiçbir şey güncellemeyecek. Veritabanınıza giden SQL komutlarını görüntüleyebiliyor musunuz (EG: MSSQL için SQL Server Profiler)? Bu şekilde hangi güncelleştirmenin oluşturulduğunu görebilir ve bu güncelleştirmenin neden hiçbir satırı etkilemediğini görebilirsiniz.
fyjham

9
Varlığın bir zaman damgası özelliği varsa, görünümünüzde sakladığınızdan ve varlığın zaman damgasını doğru şekilde doldurduğundan emin olun.
anIBMer

Bir zaman damgası sütunum vardı ve bunu ele aldığımda, EF6.1 beklendiği gibi çalıştı, @anelBMer
JQII

3
Zaman damgalarını kullanırsanız, silmek istediğiniz nesnenin başarıyla güncellenmesi için PK kümesine ve RowVersion Özelliğine ihtiyacı vardır! Nesneyi ilgili DbSet'e ekledikten sonra rowVersion (timestamp) özelliğini ayarlıyordum, bu yüzden işe yaramadı. Aferin!
Efsaneler

394

Bu durumla karşılaştım ve bunun nedeni varlığın kimlik (anahtar) alanının ayarlanmamasıydı. Böylece, bağlam verileri kaydetmeye gittiğinde, bir ID = 0 bulamadı. Güncelleme bildiriminize bir kesme noktası yerleştirdiğinizden ve varlığın kimliğinin ayarlandığından emin olun.

Paul Bellora'nın yorumundan

Gizli kimlik girişini .cshtml düzenleme sayfasına eklemeyi unutarak bu sorunu yaşadım


3
+1 Aynı sorun yaşıyordum ve bu da çözümün bulunmasına yardımcı oldu. HttpPost'ta varlık kimliğinin değerinin sıfır olmasına neden olan Sipariş modelimde [Bind (Exclude = "OrderID")] var.
Dhaust

2
Tam da bunu kaçırıyordum.
Nesnemin

4
@ Html.HiddenFor (model => model.productID) - mükemmel çalıştı. EDIT PAGE'de (MVC RAZOR) productID eksikti
Ravi Ram

2
Benzer bir sorunum vardı ama bir bükülme ile. Benim için sorun sql tablo kurulumu doğru yoktu. Birincil anahtar alanım otomatik artış olarak ayarlanmadı. Bu yüzden EF, sql'ın bu alanın otomatik olarak artan bir Kimlik alanı olduğunu söylemeyi hatırlarsanız, anahtar olmadan w / oa anahtarını eklemeye çalıştığım kaydı gönderirdi: <
Agile Noob

1
Aynı sorun ama bileşik anahtar kullanma. Anahtar değerlerden biri ayarlanmadı.
obaylis

113

Vay canına, birçok cevap, ama başka bir şeyden bahsetmediğimden biraz farklı bir şey yaptığımda bu hatayı aldım.

Uzun lafın kısası, yeni bir nesne oluşturursanız ve EF'e onun kullanılarak değiştirildiğini söylerseniz, EntityState.Modifiedbu hatayı henüz veritabanında bulunmadığı için atar. İşte benim kod:

MyObject foo = new MyObject()
{
    someAttribute = someValue
};

context.Entry(foo).State = EntityState.Modified;
context.SaveChanges();

Evet, bu saçma görünüyor, ama ortaya çıkan söz konusu yöntem foodaha önce yaratılmıştı, şimdi sadece ona someValuegeçti ve fookendini yaratıyor .

Kolay düzeltme, sadece değişim EntityState.Modifiediçin EntityState.Addedveya değiştirmek o bütün çizgi için:

context.MyObject.Add(foo);

Bunu gönderdiğiniz için teşekkürler. Bu da benim sorunum oldu, ben EntityState.Modified için Devlet ayarlayan bazı kod kopyalanmış.
clayRay

23

Aynı korkutucu hatayla karşı karşıya kaldım ... :) Sonra fark ettim ki

@Html.HiddenFor(model => model.UserProfile.UserId)

güncellenen nesnenin birincil anahtarı için! Bu basit ama çok önemli şeyi unutmaya meyilliyim!

Bu arada: HiddenForASP.NET MVC içindir.


3
Bu bir güvenlik açığı gibi görünüyor UserId, formda saklamak, bilgisayar korsanlarına çok yatkın ... daha sonra doldurulmalıdırHttpContext.Current.User.Identity.Name
Serj Sagan

@SerjSagan haklısınız ... ancak UserId ve geçerli UserName'i doğrulamak için sunucu tarafında bazı kontroller yaptığınız sürece.
Leniel Maccaferri

1
Demek istediğim , neden olsa bile onu saklamanız HiddenForgerekecek HttpContext... Bu özelliği hiç formda koymak olmaz, bu da beni her zaman sunucu tarafını doldurmaya zorlar ...
Serj Sagan

16

GridView "DataKeyNames" özniteliğini unutup unutma. GridView içindeki verileri değiştirirken bu bir zorunluluktur

http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx


+1. Benim için mükemmel ve basit bir çözüm. GridView EntityDataSource için bağlama ve bu nesne benim birincil anahtar için ayarlamadı.
Andez

Kendo kullanıcı arayüzünün bileşik anahtarı desteklemediğini biliyoruz, ancak anahtarlarımı bir araya getiren yeni bir sütun eklersem ne oluyor?
Branislav

15

Sorunun nedeni şu iki şeyden biri: -

  1. Bir veya daha fazla özelliği olan bir satırı güncellemeye çalıştınız Concurrency Mode: Fixedve İyimser Eşzamanlılık verilerin kaydedilmesini engelledi. Yani. bazıları satır verilerini sunucu verilerini aldığınız zaman ile sunucu verilerinizi kaydettiğiniz zaman arasında değiştirdi.
  2. Bir satırı güncellemeye veya silmeye çalıştınız, ancak satır mevcut değil. Bir geri alma ve kaydetme arasında verileri değiştiren (bu durumda, kaldırılan) bir başka örnek VEYA Kimlik (yani. StoreGeneratedPattern = Computed) Olmayan bir alanı güncellemeye çalıştığımız ve bu satır mevcut değil.

1
Bu, atanan tüm nesne özelliklerine daha önce sahip oldukları değerlerle atanmışsa da neden olabilir.
Serj Sagan

Birincisi için +1. StoreGeneratedPattern = Yok vardı, StoreGeneratedPattern = Kimlik olarak değiştirmek sorunu çözdü. Teşekkürler
tkt986

12

PK parçası bir datetime sütun olduğu ve eklenen kayıt DateTime.Now bu sütun için değer olarak kullanılan çünkü aynı hatayı aldım. Varlık çerçevesi, değeri milisaniye hassasiyetle ekler ve daha sonra yeni girdiği değeri milisaniye hassasiyetle arar. Ancak SqlServer değeri ikinci hassasiyete yuvarlamış ve bu nedenle varlık çerçevesi milisaniye hassasiyet değerini bulamamıştır.

Çözüm, yerleştirmeden önce DateTime.Now milisaniye kesecekti.


2
Değeri Dateolan bir sütuna DateTime
eklememiz

1
Burada aynı. Veri ambarı kaydımız vardı ve zaman damgasını anahtarın bir parçası olarak kullanıyorduk. Veri ambarındaki zaman damgası bir SQL DateTime idi, ancak C # içindeki zaman damgası eşleşmiyordu. SQL veri türünü DateTime2 (7) olarak değiştirdim, EF modelini güncelledim ve hepsi düzeltildi.
mmcfly

Sütunu Datetime2 (7) olarak değiştirmek de benim için çalıştı. Thanks @mmcfly
Dzejms

10

Aynı sorunu yaşıyordum ve @ webtrifusion'un cevabı çözümü bulmaya yardımcı oldu.

Benim modelim kullanıyordu Bind(Exclude)HttpPost üzerinde sıfır edilmesi için taraf kimliği değerini neden olan tarafın kimliği özelliği.

namespace OrderUp.Models
{
[Bind(Exclude = "OrderID")]
public class Order
{
    [ScaffoldColumn(false)]
    public int OrderID { get; set; }

    [ScaffoldColumn(false)]
    public System.DateTime OrderDate { get; set; }

    [Required(ErrorMessage = "Name is required")]
    public string Username { get; set; }
    }
}   

Benzer bir sorun, güvenlik nedeniyle, Bind var (include = bazı alanlar). Kimlik listede yoktu. Ayrıca gizli bir girdi olarak ekledim. MVC tarafından oluşturulan bir şeyi silmiş olmalı veya kimlik hiç yoktu. Yardım için teşekkürler.
MusicAndCode

10

Aynı sorunu yaşadım, bunun boş olan RowVersion'dan kaynaklandığını anladım. Senin olmadığını kontrol Kimliği ve rowversion olan boş değil .

daha fazla bilgi için bu eğiticiye bakın

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application


benim durumumda satır sürümü null
Prakash

Benim durumumda yanlışlıkla [Bağlama (Include = özellikler)] Id alanı kaldırmıştı. Geri ekleyin ve iyi çalıştı.
Caverman

8

İlk önce kod ilk kod değiştirdikten sonra bu hatayı almaya başladı. Birden fazla iş parçacığı bazı aynı satırı güncelleyebilir bir veritabanı güncelleştirme var. Neden önce model kullanarak bir sorunum olmadığını bilmiyorum, farklı bir eşzamanlılık varsayılanı kullandığını varsayın.

Oluşabilecek koşulları bilerek tek bir yerde işlemek için DbContext sınıfıma aşağıdaki aşırı yüklenmeyi ekledim:

using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;

public class MyDbContext: DbContext {
...
        public int SaveChanges(bool refreshOnConcurrencyException, RefreshMode refreshMode = RefreshMode.ClientWins) {
            try {
                return SaveChanges();
            }
            catch (DbUpdateConcurrencyException ex) {
                foreach (DbEntityEntry entry in ex.Entries) {
                    if (refreshMode == RefreshMode.ClientWins)
                        entry.OriginalValues.SetValues(entry.GetDatabaseValues());
                    else
                        entry.Reload();
                }
                return SaveChanges();
            }
        }
}

Daha sonra uygun olan SaveChanges(true)her yerde çağrılır .


1
Tamam, herkes sorundan şikayet ediyor, nasıl tetikleyebileceklerini vb. Gösteriyor, ancak bu cevabın havalı bir cevabı var. Devam güncelleme modelini kullanıyorum (burada kaydet düğmesi yok bebeğim) ve EF iş parçacığı geride kaldığında ızgara güncellemelerinde bunu alıyordum ve çözdüm. Harika bir iş benim iyi adım .. beni bir kahraman gibi gösterdin - devlerin omzunda duran !!
Tony Trembath-Drake

Bana da yardımcı oldu, daha fazla
seçenek için şuna bakın-

7

Birincil anahtarın BoundField öğesini açıkça eklemeniz gerekir. Kullanıcının birincil anahtarı görmesini istemiyorsanız, css yoluyla gizlemeniz gerekir:

    <asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden" 
HeaderStyle-CssClass="hidden" />

'Hidden', css'de ekranını 'none' olarak ayarlanmış bir sınıftır.


1
hah, ASP.NET MVC gizli kimlik alanımı sildiğim gerçeği bana ipucu. Teşekkürler @Paulo! :)
Tomasz Iniewicz

7

Düzenleme sırasında görünümde gizli alan olarak varlığın kimliğini veya birincil anahtarını ekleyin

yani

      @Html.HiddenFor(m => m.Id)

sorunu çözer.

Ayrıca modelinizde kullanılmayan bir öğe varsa bunu da ekleyin ve denetleyiciye gönderin


7

Bu hatayla da karşılaştım. Ortaya çıkan sorun, kaydetmeye çalıştığım masadaki bir Tetikleyiciden kaynaklandı. Tetikleyici 'INSTEAD OF INSERT' komutunu kullandı; bu, o tabloya hiç 0 satır eklendiği ve dolayısıyla hata olduğu anlamına gelir. Neyse ki, tetikleme işlevselliği yanlış olabilir, ancak sanırım bir şekilde kod ele alınması gereken geçerli bir işlem olabilir. Umarım bu bir gün birine yardım eder.


2
Varlık, tetikleyiciden bir SELECT ifadesi (birincil anahtar sütunu ile) döndürülerek satırların eklendiğine inanarak kandırılabilir.
jahu

1
@Jahu'nun yorumunu genişletmek için, tetikleyicimden döndürülecek yeni eklenen öğenin gerçek bir kimliğini almak zorunda kaldım ve sütun adı tetikleyici tablosunun kimlik sütunuyla eşleşmelidir (benim durumumda, aslında bir görünüm kendi kimliğine sahip değilim ama edmx'i olduğuna inanmak için kandırmıştım). Tetikleyicim ayrı bir tabloya bir ekleme yapıyordu, bu yüzden bu son satırı tetikleyicime SELECT SCOPE_IDENTITY() as MyViewId
ekledim


Benim durumumda, bir alt koleksiyondaki varlıklar üzerinde bir silme işlemi yapıyordum, ancak alt varlıklardan biri için başka bir alt varlığın silinmesine neden olan silme işlemi için bir tetikleyici vardı. Varlık çerçevesi silmeye çalışmadan önce alt varlıklardan birinin silinmesi tetikleyicisi nedeniyle N - 1 satırları etkilendiğinden bu hataya neden oldu.
skeletank

6

Birincil anahtarı eksik olan ve bir DATETIME (2, 3) sütunu olan bir tabloda bu sorunla karşılaştım (böylece varlığın "birincil anahtarı" tüm sütunların birleşimiydi) ... Ekleme yaparken zaman damgası vardı daha kesin bir zaman (2018-03-20 08: 29: 51.8319154) kesildi (2018-03-20 08: 29: 51.832), böylece anahtar alanlardaki arama başarısız oluyor.


5

Bu hatayı da aldım. Varlığın, kullandığınız gerçek Veritabanı Bağlamından haberdar olamayabileceği veya Modelin farklı olabileceği bazı durumlar vardır. Bunun için set: EntityState.Modified; için EntityState. Added;

Bunu yapmak için:

if (ModelState.IsValid)
{
context.Entry(yourModelReference).State = EntityState.Added;
context.SaveChanges();
}

Bu, Kurumun birlikte çalıştığınız Durumu kullandığınızı veya eklediğinizi bilmesini sağlar. Bu noktada tüm doğru Model Değerlerinin ayarlanması gerekir. Arka planda yapılmış olabilecek herhangi bir değişikliği kaybetmemeye dikkat edin.

Bu yardımcı olur umarım.


1
sen bir gurun! benim için çalışıyor!
Hernaldo Gonzalez

5
  @Html.HiddenFor(model => model.RowVersion)

Benim rowversion null, bu yüzden benim sorunum çözüldü görünümüne eklemek zorunda kaldı


RowVersion görünümünden düzenleme eylemine geçmiyordu, ayrıca RowVersion için model bağlama yapmayı unuttum. Nesneyi db'ye kaydederken, eşzamanlılık denetimi nesnesiyle birlikte db'ye RowVersion gönderiminin önceki değerine ihtiyacınız vardır. İşlere daha hızlı ihtiyacınız olduğunda aptalca hatalar yaparsınız!
Dhanuka777

5

[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]Benim durumumda hat hile yaptı:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;


[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? SomeNumber { get; set; }

4

Tablo ve formun hem birincil anahtarın hem de edmx'in güncellendiğinden emin olun.

güncelleme sırasında herhangi bir hata genellikle nedeniyle bulundu: - Tablo birincil anahtar yok - Görünümü / formu Düzenle birincil anahtar yok (örneğin @Html.HiddenFor(m=>m.Id)


4

Ben de aynı problemi yaşadım. Benim durumumda, izin verilmeyen birincil anahtarı güncellemeye çalışıyordum.


4

Bir asyncyöntem kullanırken bu hatayı düzensiz olarak aldım . Senkron bir yönteme geçildiğimden beri olmadı.

Hatalar ara sıra:

[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public async Task<IHttpActionResult> Delete(int id, int customerId)
{
    var file = new Models.File() { Id = id, CustomerId = customerId };
    db.Files.Attach(file);
    db.Files.Remove(file);

    await db.SaveChangesAsync();

    return Ok();
}

Her zaman çalışır:

[Authorize(Roles = "Admin")]
[HttpDelete]
[Route("file/{id}/{customerId}/")]
public IHttpActionResult Delete(int id, int customerId)
{
    var file = new Models.File() { Id = id, CustomerId = customerId };
    db.Files.Attach(file);
    db.Files.Remove(file);

    db.SaveChanges();

    return Ok();
}

Her ne kadar bu sorunumu çözse de, daha önce bu yazıda PKs & Row sürümleri hakkında bahsedilen temel konuya işaret etti. PK'nın adlandırma kuralı kuralına uymaması nedeniyle daha karmaşık olan yeni bir tablo için bir şema haritası eklemeyi ihmal etmiştim. <Tablo Adı> Kimliği.
midohioboarder

3

Ben DB (döngü içinde) bazı satırları silme ve aynı tabloda yenilerini eklerken bu hatayı aldım.

Benim için çözümler, her döngü yinelemesinde dinamik olarak yeni bir bağlam oluşturmaktı


Aynı şeyi yapmak zorunda kaldım, sorunun neden ilk etapta olduğundan emin değilim, ama bu işe yarıyor.
Jed Grant

3
    public void Save(object entity)
    {
        using (var transaction = Connection.BeginTransaction())
        {
        try
                {
                    SaveChanges();
                    transaction.Commit();
                }
                catch (OptimisticConcurrencyException)
                {
                    if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
                        this.Refresh(RefreshMode.StoreWins, entity);
                    else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
                        Detach(entity);
                    AcceptAllChanges(); 
                    transaction.Commit();
                }
        }
    }

Burada 'neyin' neyi ifade ettiğini ve ObjectStateManager'ın ne olduğunu açıklayabilir misiniz? Bunu temel depo sınıfımızda deniyorum ama hata alıyorum
Naomi

3

Bu, benzersiz bir kısıtlama durumuna girmeye çalışıyorsanız da gerçekleşir, yani işveren başına yalnızca bir tür adresiniz varsa ve aynı işverene aynı türden bir saniye eklemeye çalışırsanız, aynı sorunu yaşarsınız. .

VEYA

Bu, atanan tüm nesne özelliklerine daha önce sahip oldukları değerlerle atanmışsa da olabilir.

        using(var db = new MyContext())
        {
            var address = db.Addresses.FirstOrDefault(x => x.Id == Id);

            address.StreetAddress = StreetAddress; // if you are assigning   
            address.City = City;                   // all of the same values
            address.State = State;                 // as they are
            address.ZipCode = ZipCode;             // in the database    

            db.SaveChanges();           // Then this will throw that exception
        }

2

Edmx dosyanızda bir "Imports işlevi" ile eşleme oluşturmaya çalışıyorsanız, bu hataya neden olabilir. Sadece edmx'inizdeki belirli bir varlığın Haritalama Ayrıntıları'nda bulunan ekleme, güncelleme ve silme alanlarını temizleyin ve çalışması gerekir. Umarım açıklığa kavuştum.


2

Veritabanında var olmayan bir nesneyi eklerken bu istisnayı aldım. Nesnenin ayrı bir bağlamdan yüklendiğini varsaymıştım, ancak kullanıcının siteyi ilk kez ziyaret etmesi halinde, nesne sıfırdan oluşturuldu. Otomatik olarak artan birincil anahtarlarımız var, bu yüzden değiştirebilirim

context.Users.Attach(orderer);

ile

if (orderer.Id > 0) {
    context.Users.Attach(orderer);
}

2

Ben de aynı sorunu yaşıyorum. Ama bu benim hatamdan kaynaklanıyordu. Aslında eklemek yerine bir nesneyi kaydediyordum. Çatışma buydu.


2

Bu sorunu Sql Server ortamında hata ayıklamanın bir yolu, SqlServer kopyanızla birlikte gelen Sql Profiler'ı kullanmaktır veya Express sürümünü kullanıyorsanız aşağıdaki bağlantıyı kullanarak Express Profiler'ın bir kopyasını CodePlex'ten ücretsiz olarak alabilirsiniz:

Ekspres Profilci

Sql Profiler kullanarak EF tarafından DB'ye gönderilen her şeye erişebilirsiniz. Benim durumumda:

exec sp_executesql N'UPDATE [dbo].[Category]
SET [ParentID] = @0, [1048] = NULL, [1033] = @1, [MemberID] = @2, [AddedOn] = @3
WHERE ([CategoryID] = @4)
',N'@0 uniqueidentifier,@1 nvarchar(50),@2 uniqueidentifier,@3 datetime2(7),@4 uniqueidentifier',
@0='E060F2CA-433A-46A7-86BD-80CD165F5023',@1=N'I-Like-Noodles-Do-You',@2='EEDF2C83-2123-4B1C-BF8D-BE2D2FA26D09',
@3='2014-01-29 15:30:27.0435565',@4='3410FD1E-1C76-4D71-B08E-73849838F778'
go

Bu kopyayı Sql Server'daki bir sorgu penceresine yapıştırdı ve yürüttüm. Her ne kadar çalışsa da, 0 kayıt bu sorgudan etkilendi ve EF tarafından döndürülen hata.

Benim durumumda sorun CategoryID neden oldu.

EF kimliği tarafından veritabanına gönderilen bir CategoryID tanımlanmadığından 0 kayıt etkilenir.

Bu EF'in hatası değil, daha ziyade hatalı bir boşaltma "??" veri katmanına saçmalık gönderen bir View Controller'da bildirimde bulunun.


2

Yukarıdaki cevapların hiçbiri durumumu ve çözümünü tam olarak kapsamamıştır.

MVC5 denetleyicisinde hatanın atıldığı kod:

        if (ModelState.IsValid)
        {
            db.Entry(object).State = EntityState.Modified; 
            db.SaveChanges(); // line that threw exception
            return RedirectToAction("Index");
        }

Bu istisnayı, bir nesneyi Düzenleme görünümünden kaydederken aldım. Onu atmanın nedeni, onu kurtarmak için geri döndüğümde, nesne üzerinde birincil anahtarı oluşturan özellikleri değiştirmiştim. Bu nedenle, durumunu Değiştirilmiş olarak ayarlamak EF için bir anlam ifade etmiyordu - daha önce kaydedilmiş olan değil, yeni bir girişti.

Bunu A) kaydetme çağrısını Nesne ekle olarak değiştirerek veya B) düzenleme sırasında birincil anahtarı değiştirmeyerek çözebilirsiniz. B yaptım).


2

Kabul edilen cevap, " uygulamanızın bilmediği bir değişikliğin üzerine yazılmayacak " dediğinde , nesnem yeni oluşturulduğu için şüpheliydim. Ama sonra ortaya çıktı, INSTEAD OF UPDATE, INSERT- TRIGGERaynı tablonun hesaplanmış bir sütununu güncelleyen tabloya bir ek vardı.

Bunu bir kez değiştirdiğimde AFTER INSERT, UPDATE, iyi çalışıyordu.


2

Bu bana datetime ve datetime2 arasındaki bir uyumsuzluk nedeniyle oldu. Garip bir şekilde, bir test cihazının sorunu keşfetmesinden önce iyi çalıştı. My Code First modelinde birincil anahtarın bir parçası olarak bir DateTime vardı:

[Key, Column(Order = 2)]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;

Oluşturulan sütun bir tarih / saat sütunudur. SaveChanges çağrılırken EF aşağıdaki SQL'i oluşturdu:

-- Region Parameters
DECLARE @0 Int = 2
DECLARE @1 Int = 25
DECLARE @2 Int = 141051
DECLARE @3 DateTime2 = '2017-07-27 15:16:09.2630000' --(will not equal a datetime value)
-- EndRegion
UPDATE [dbo].[OrganizationSurvey]
SET [OrganizationSurveyStatusId] = @0
WHERE ((([SurveyID] = @1) AND ([OrganizationID] = @2)) AND ([PurchasedDate] = @3))

Bir datetime sütununu datetime2 değeriyle eşleştirmeye çalıştığı için sonuç döndürmedi. Düşünebildiğim tek çözüm, sütunu datetime2 olarak değiştirmekti:

[Key, Column(Order = 2, TypeName = "DateTime2")]  
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;

1
Çalışmaya karşı çalışmamanın tuhaflığı, vs.'nin temel formatı / tabanı datetimeile ilgilidir datetime2. Temelde bazı milisaniye değerleri bir eşleşmeyi değerlendirir, bazıları ise değerlendirmez. Bana da aynı şey oldu ve ben de değiştim DateTime2.
xr280xr

+1 Keşke bunun için +100 yapabilseydim. Birçok yerde dolaştıktan sonra nihayet bunu buldum ve aslında, birincil anahtarımın bir parçası olarak bir Datetime yaşadığımı fark ettim. Evet, bu gerçekten düzeltildi. Sütunu Datetime2 olarak güncelledim ve işe yaradı. Şimdi, benim sığır eti Entity Framework ile böyle boktan bir sorgu yapmak için beni bunu yapmaya zorlar.
21'de Katolikler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.