'DF __ *' nesnesi '*' sütununa bağımlı - int değerini iki katına değiştirme


170

Temel olarak EF veritabanımda aşağıdaki özelliklere sahip bir tablo var:

public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Image { get; set; }
public string WatchUrl { get; set; }
public int Year { get; set; }
public string Source { get; set; }
public int Duration { get; set; }
public int Rating { get; set; }
public virtual ICollection<Category> Categories { get; set; }

Ancak Rating int bir çift olarak değiştirdiğinizde iyi çalışır Veritabanını güncellerken aşağıdaki hatayı alıyorum:

'DF_ Movies _Rating__48CFD27E' nesnesi ' Derecelendirme' sütununa bağlıdır. ALTER TABLE ALTER COLUMN Bir veya daha fazla nesne bu sütuna eriştiği için derecelendirme başarısız oldu.

Sorun nedir?


1
DF_Movies_Rating__48CFD27E kısıtlamasını kaldırın ve ardından alanınızın türünü değiştirin
Joe Taras

@JoeTaras Ama ben hiç böyle bir kısıtlama yaratmadım. Nedir ve nerede bulabilirim?
Jordan Ax

2
Bir alan oluşturduğunuzda DBMS otomatik olarak bir kısıt oluşturur. Tablo bilgilerinizi genişletirseniz, kısıtlama bölümünde bulabilirsiniz. Bana bulabilirsen söyle;)
Joe Taras

Yanıtlar:


253

Bunu dene:

Alan türünüzü değiştirmeden önce DF_Movies_Rating__48CFD27E kısıtlamasını kaldırın .

Kısıtlama genellikle DBMS (SQL Server) tarafından otomatik olarak oluşturulur.

Tabloyla ilişkili kısıtlamayı görmek için, Nesne gezgininde tablo niteliklerini , ardından aşağıda gösterildiği gibi kategori Sınırlamaları'nı genişletin :

Masanızın ağacı

Alan türünü değiştirmeden önce kısıtlamayı kaldırmanız gerekir.


40
@ManirajSS: ALTER TABLE yourtable DROP CONSTRAINT DF_Movies_Rating__48CFD27E
Joe Taras

18
Kısıtlamanın yaratılmasını ne tetikledi? Onlardan bir sürü var ve onları gerçekten istemiyorum!
Simon Parker

5
Hmm, ve benim çerçeve (Laravel) ve dropColumn DB geçişlerini kullanmak istiyorum ne yapmalıyım? Gizemli bir adı olan kısıtlamayı nasıl bırakacağım hakkında hiçbir fikrim yok, SQL sunucusu tarafından otomatik olarak oluşturuldu :(
JustAMartin

2
Eminim: Onu bıraktım ve Kısıtlamalar klasörü boş olur ve uygulamayı çalıştırdığımda veya update-databasekendisini yeniden oluşturduğumda bu sorunu gönderdim: stackoverflow.com/questions/40267769/…
mshwf

2
Neden SQLServer zıttı örtük olarak düşürmez? Sonuçta, örtük olarak yarattı!
youcantryreachingme

46

Bu tsqlyol

 ALTER TABLE yourtable DROP CONSTRAINT constraint_name     -- DF_Movies_Rating__48CFD27E

Tamlık için, bu sadece @Joe Taras'ın yorumunu bir cevap olarak gösterir


46

Bunu, kısıtlamanın nereden geldiğini açıklamak için bir yanıt olarak ekliyorum. Yorumlarda yapmaya çalıştım ama orada güzel düzenlemek zor: - /

Varsayılan değerlere sahip bir sütunu olan bir tablo oluşturursanız (veya değiştirirseniz), sizin için kısıtlama oluşturur.

Örneğin, tablonuzda şunlar olabilir:

CREATE TABLE Movie (
    ...
    rating INT NOT NULL default 100
)

Varsayılan 100 için bir kısıt oluşturur.

Bunun yerine böyle oluşturursanız

CREATE TABLE Movie (
  name VARCHAR(255) NOT NULL,
  rating INT NOT NULL CONSTRAINT rating_default DEFAULT 100
);

Daha sonra, söz konusu tabloyu değiştirirken referans vermesi daha kolay adlandırılmış bir kısıtlama alırsınız.

ALTER TABLE Movie DROP CONSTRAINT rating_default;
ALTER TABLE Movie ALTER COLUMN rating DECIMAL(2) NOT NULL;
-- sets up a new default constraint with easy to remember name
ALTER TABLE Movie ADD CONSTRAINT rating_default DEFAULT ((1.0)) FOR rating;

Bu son 2 ifadeyi birleştirerek sütunu değiştirebilir ve kısıtlamayı tek bir satırda adlandırabilirsiniz (zaten bir tablo olup olmadığını bilmeniz gerekir)


İlk olarak tüm kısıtlamaları adlandırarak sorunun nasıl önleneceği hakkında bilgi eklediğiniz için teşekkür ederiz. (Yani, rastgele adlandırılmış kısıtlamaları düşürme sorununu önleyin)
youcantryreachingme

22

Kısıtlamanın öngörülemeyen bir adı olduğundan, adını bilmeden kaldırmak için özel komut dosyası ( DropConstraint ) yazabilirsiniz ( EF 6.1.3'te test edilmiştir):

public override void Up()
{    
    DropConstraint();
    AlterColumn("dbo.MyTable", "Rating", c => c.Double(nullable: false));
}

private void DropConstraint()
{
    Sql(@"DECLARE @var0 nvarchar(128)
          SELECT @var0 = name
          FROM sys.default_constraints
          WHERE parent_object_id = object_id(N'dbo.MyTable')
          AND col_name(parent_object_id, parent_column_id) = 'Rating';
          IF @var0 IS NOT NULL
              EXECUTE('ALTER TABLE [dbo].[MyTable] DROP CONSTRAINT [' + @var0 + ']')");
}

public override void Down()
{            
    AlterColumn("dbo.MyTable", "Rating", c => c.Int(nullable: false));    
}

Bu yanıt, sabit kod kısıtlama adını göze alamayacağınız Göç tabanlı bir ortamda harika çalışır.
Menion Leah

AlterColumn için - AlterColumnX gibi - bir sarmalayıcı / uzantı / aşırı yük işlevi yaparsanız, o DropConstraint mantığını oraya dahil edebilirsiniz - ve tablo adını ve sütun adını ileterek tekrar yazmanıza gerek kalmaz.
N73k

10

MS SQL Studio, sütunu sildiğinizde ilgilenir, ancak Kısıtlamayı Programlı olarak Silmeniz gerekiyorsa, burada basit bir çözümdür.

Varsayılan bir kısıtlamaya sahip bir sütunu bırakacak bir kod snippet'i aşağıdadır:

DECLARE @ConstraintName nvarchar(200)
SELECT @ConstraintName = Name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = OBJECT_ID('__TableName__') AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns WHERE NAME = N'__ColumnName__' AND object_id = OBJECT_ID(N'__TableName__'))
IF @ConstraintName IS NOT NULL
EXEC('ALTER TABLE __TableName__ DROP CONSTRAINT ' + @ConstraintName)
IF EXISTS (SELECT * FROM syscolumns WHERE id=object_id('__TableName__') AND name='__ColumnName__')
EXEC('ALTER TABLE __TableName__ DROP COLUMN __ColumnName__')

Yalnızca TableName ve ColumnName değerlerini uygun değerlerle değiştirin. Sütun zaten bırakılmış olsa bile bunu güvenle çalıştırabilirsiniz.

Bonus : Yabancı anahtarları ve diğer kısıtlama türlerini bırakma kodu.

IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '__TableName__' AND COLUMN_NAME = '__ColumnName__')
BEGIN
SELECT @ConstraintName = CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '__TableName__' AND COLUMN_NAME = '__ColumnName__'
EXEC('ALTER TABLE __TableName__ DROP CONSTRAINT ' + @ConstraintName)
END

Blog


1
Hayatımı iki kez kurtardım. Her ikisi de, kontrol kısıtlamalarını silmek zorunda. Her şeyden önce ilk sorguyu kullanmak zorunda. İkinci olarak, SYS.DEFAULT_CONSTRAINTS tablosunda kontrol kısıtlaması bulunamadığından ikinci sorguyu kullanmak zorundayım. Çok teşekkürler!
Pazar

8

Bağlı bir sütunu bırakmaya çalıştığımızda bu tür bir hata görüyoruz:

'DF __ *' nesnesi '' sütununa bağlıdır.

bu sütuna bağımlı olan kısıtlamayı şununla bırakın:

ALTER TABLE TableName DROP CONSTRAINT dependent_constraint;

Misal:

Msg 5074, Seviye 16, Durum 1, Satır 1

' DF__Employees__Colf__1273C1CD' nesnesi ' Colf' sütununa bağlıdır.

Msg 4922, Seviye 16, Durum 9, Satır 1

ALTER TABLE DROP COLUMN Colf, bir veya daha fazla nesne bu sütuna eriştiği için başarısız oldu.

Düşme Sınırlaması (DF__Employees__Colf__1273C1CD):

ALTER TABLE Employees DROP CONSTRAINT DF__Employees__Colf__1273C1CD;

Sonra Sütun Bırakabilirsiniz:

Alter Table TableName Drop column ColumnName

1

Çözüm :

veritabanı tablosunu aç -> tabloyu genişlet -> kısıtlamaları genişlet ve bunu gör

ekran görüntüsü


Bu kod soruyu cevaplayabilirken, bu kodun soruyu neden ve / veya nasıl cevapladığı konusunda ek bağlam sağlamak uzun vadeli değerini arttırır.
Donald Duck

-1

Etrafında çalışmak için bir geçiş çalıştırmak çalışırken bu hatayı aldım sütun yeniden adlandırdı ve kullanarak geçiş yeniden oluşturulan

add-migration migrationname -force

paket yöneticisi konsolunda. Sonra koşabildim

update-database

Başarıyla.


2
Dikkatli olun, bu bir sütunu yeniden adlandırmaz - sütunu bırakır ve yeni bir sütun ekler. Taşıma işlemine özel kod eklemediğiniz sürece, sütunda mevcut olan tüm verileri kaybedersiniz.
Caesay
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.