14

का उपयोग करने के बाद त्रुटि हम इकाई फ्रेमवर्क 5.0 कोड प्रथम और स्वचालित माइग्रेशन का उपयोग कर रहे हैं।ईएफ 5 कोड प्रथम माइग्रेशन: "प्रत्येक तालिका में कॉलम नाम अद्वितीय होना चाहिए" RenameColumn

मैं बहुत की तरह एक वर्ग था:

public class TraversalZones 
{ 
    public int Low { get; set; } 
    public int High { get; set; } 
}​ 

तब हमने महसूस किया इन गुणों वास्तव में सही नाम नहीं थे, इसलिए हम उन्हें बदल दिया है:

public class TraversalZones 
{ 
    public int Left { get; set; } 
    public int Top { get; set; } 
}​ 

नाम बदलने परियोजना भर में ठीक से पुनर्संशोधित , लेकिन मुझे पता है कि स्वचालित माइग्रेशन आईडीई में इन स्पष्ट नामों को लेने के लिए पर्याप्त स्मार्ट नहीं हैं, इसलिए मैंने पहली बार सत्यापित किया कि केवल लंबित माइग्रेशन सत्यापित करने के लिए यह कॉलम नाम था:

update-database -f -script 

निश्चित रूप से यह सिर्फ एसक्यूएल को कम और उच्च ड्रॉप और बाएं और शीर्ष जोड़कर दिखाया गया है। मैं तो एक मैनुअल प्रवास कहा:

add-migration RenameColumns_TraversalZones_LowHigh_LeftTop 

और बस उत्पन्न कोड तय:

public override void Up() 
{ 
    RenameColumn("TraversalZones", "Low", "Left"); 
    RenameColumn("TraversalZones", "High", "Top"); 
} 

public override void Down() 
{ 
    RenameColumn("TraversalZones", "Left", "Low"); 
    RenameColumn("TraversalZones", "Top", "High"); 
} 

मैं तो डाटाबेस अद्यतन:

update-database -verbose 

और 2 स्तंभ renames मिला , जैसा कि मैं उम्मीद कर रहा था।

कई माइग्रेशन बाद में मैंने उत्पादन का बैक अप लिया और इसे डीबी पर कोड का परीक्षण करने के लिए स्थानीय डीबी में बहाल कर दिया। यह डीबी पहले से ही में बनाया TraversalZones मेज, पुराने स्तंभ नाम (निम्न और उच्च) के साथ निश्चित रूप से मैं इसे अद्यतन करने से शुरू हुआ था:

update-database -f -verbose 

और नाम बदलें आदेशों उत्पादन में दिखाई दिया - सब कुछ ठीक दिखाई नहीं दी:

EXECUTE sp_rename @objname = N'TraversalZones.Low', @newname = N'Left', @objtype = N'COLUMN' 
EXECUTE sp_rename @objname = N'TraversalZones.High', @newname = N'Top', @objtype = N'COLUMN' 
[Inserting migration history record] 

तब मैंने अपना कोड चलाया, और यह पता चला कि मुझे अंतिम रन के बाद डेटाबेस बदल गया था, और मुझे update-database चलाया जाना चाहिए ...।

तो मैं इसे फिर से भाग गया:

update-database -f -verbose 

और अब इस त्रुटि पर अटक कर रहा हूँ:

No pending code-based migrations. Applying automatic migration: 
201212191601545_AutomaticMigration. 
ALTER TABLE [dbo].[TraversalZones] ADD [Left] [int] NOT NULL DEFAULT 0 
System.Data.SqlClient.SqlException (0x80131904): Column names in each table must be unique. Column name 'Left' in table 'dbo.TraversalZones' is specified more than once. 
    at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
    at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) 
    at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) 
    at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) 
    at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout) 
    at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite) 
    at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements) 
    at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading, Boolean auto) 
    at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading) 
    at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
    at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 
    at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) 
    at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore() 
    at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run() 
ClientConnectionId:c40408ee-def3-4553-a9fb-195366a05fff 
Column names in each table must be unique. Column name 'Left' in table 'dbo.TraversalZones' is specified more than once.​ 

तो, स्पष्ट रूप से माइग्रेशन कॉलम "वाम" अभी भी करने की जरूरत है कि क्या करने के लिए के रूप में उलझन में है यह इस तालिका में; मुझे लगता है कि RenameColumn उचित स्थिति में चीजें छोड़ देगा, लेकिन ऐसा लगता है कि यह नहीं है।

जब मैं डंप यह एक update-database -f -script को क्या करने की कोशिश कर रहा है क्या, मैं इसे यह वास्तव में क्या किया होता करने के लिए कोशिश कर रहा है, तो मैनुअल प्रवास वहाँ नहीं थे मिलती है:

ALTER TABLE [dbo].[TraversalZones] ADD [Left] [int] NOT NULL DEFAULT 0 
ALTER TABLE [dbo].[TraversalZones] ADD [Top] [int] NOT NULL DEFAULT 0 
DECLARE @var0 nvarchar(128) 
SELECT @var0 = name 
FROM sys.default_constraints 
WHERE parent_object_id = object_id(N'dbo.TraversalZones') 
AND col_name(parent_object_id, parent_column_id) = 'Low'; 
IF @var0 IS NOT NULL 
    EXECUTE('ALTER TABLE [dbo].[TraversalZones] DROP CONSTRAINT ' + @var0) 
ALTER TABLE [dbo].[TraversalZones] DROP COLUMN [Low] 
DECLARE @var1 nvarchar(128) 
SELECT @var1 = name 
FROM sys.default_constraints 
WHERE parent_object_id = object_id(N'dbo.TraversalZones') 
AND col_name(parent_object_id, parent_column_id) = 'High'; 
IF @var1 IS NOT NULL 
    EXECUTE('ALTER TABLE [dbo].[TraversalZones] DROP CONSTRAINT ' + @var1) 
ALTER TABLE [dbo].[TraversalZones] DROP COLUMN [High] 
INSERT INTO [__MigrationHistory] ([MigrationId], [Model], [ProductVersion]) VALUES ('201212191639471_AutomaticMigration', 0x1F8B08000...000, '5.0.0.net40') 

इस में एक बग प्रतीत होता है माइग्रेशन।

उत्तर

15

वैकल्पिक हल, जाहिर है, यह है:

update-database -f -script 

जो तुम मेरे सवाल में के परिणाम देख सकते हैं। तब मैंने स्क्रिप्ट से सब कुछ फेंक दिया लेकिन आखिरी पंक्ति, और डीबी के खिलाफ माइग्रेशन को जाने के लिए भाग गया: हम पहले ही उस कॉलम का नाम बदल चुके हैं, इसे काट लें।

अब मैं के साथ डेटाबेस की प्रतिलिपि के साथ आगे बढ़ सकता हूं, लेकिन मुझे उत्पादन की प्रतियों के प्रति हर प्रवासन का सवाल है (जब तक उत्पादन खुद को माइग्रेट नहीं किया जाता) इस मुद्दे को जारी रखेगा। इस कामकाज के बिना मैं इसे ठीक से कैसे हल कर सकता हूं?

अद्यतन

यह उत्पादन सहित हर दूसरे उदाहरण में एक मुद्दा वास्तव में था। गंदे समाधान उत्पन्न संस्करण और निश्चित संस्करण को करने के बाद, एक SQL स्क्रिप्ट (update-database -f -script) उत्पन्न करना था। तो ठीक

public void Up() 
{ 
    Sql("...That SQL you extracted from the script..."); 
} 

यह अन्य वातावरण इस माइग्रेशन चलाने सुनिश्चित करेगा कार्य करें:

एक थोड़ा सफाई घोल, स्क्रिप्ट से एसक्यूएल ले एक मैनुअल प्रवास जोड़ने के लिए, और बस के लिए ऊपर की सामग्री को बदलने के लिए है जिस तरह से आप इरादा किया।

  1. बैकअप सिर्फ मामले में अपने डाटाबेस:

    परीक्षण इस थोड़ा मुश्किल है ताकि आप इसे इस तरह से संपर्क कर सकते हैं है।

  2. एसक्यूएल चलाएं। अगर यह ठीक से काम करता है, तो एसक्यूएल को अलग करें।
  3. मैन्युअल माइग्रेशन जोड़ें और ऊपर() विधि में सब कुछ मिटा दें। इसे पूरी तरह खाली छोड़ दें।
  4. रन अपडेट-डेटाबेस -f
  5. अब Sql("..."); को आपके द्वारा सेट किए गए SQL को कॉल करके ऊपर() विधि को संशोधित करें।

अब आपका डीबी दो बार एसक्यूएल चलाने के बिना अद्यतित है, और अन्य वातावरण उस SQL ​​के परिणाम प्राप्त करते हैं।

संबंधित मुद्दे