2012-05-16 13 views
7

प्रारंभ करने के लिए कोड जोड़ने के लिए मैं कोडफर्स्ट का उपयोग करता हूं और मैं एल्मा का उपयोग करता हूं। मैं हर बार डेटाबेस निर्मित, तो आप मैन्युअल फ़ाइल से कोड जोड़ना होगा:एसक्यूएल डेटाबेस

/* 

    ELMAH - Error Logging Modules and Handlers for ASP.NET 
    Copyright (c) 2004-9 Atif Aziz. All rights reserved. 

    Author(s): 

     Atif Aziz, http://www.raboof.com 
     Phil Haacked, http://haacked.com 

    Licensed under the Apache License, Version 2.0 (the "License"); 
    you may not use this file except in compliance with the License. 
    You may obtain a copy of the License at 

     http://www.apache.org/licenses/LICENSE-2.0 

    Unless required by applicable law or agreed to in writing, software 
    distributed under the License is distributed on an "AS IS" BASIS, 
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
    See the License for the specific language governing permissions and 
    limitations under the License. 

*/ 

-- ELMAH DDL script for Microsoft SQL Server 2000 or later. 

-- $Id: SQLServer.sql 677 2009-09-29 18:02:39Z azizatif $ 

DECLARE @DBCompatibilityLevel INT 
DECLARE @DBCompatibilityLevelMajor INT 
DECLARE @DBCompatibilityLevelMinor INT 

SELECT 
    @DBCompatibilityLevel = cmptlevel 
FROM 
    master.dbo.sysdatabases 
WHERE 
    name = DB_NAME() 

IF @DBCompatibilityLevel <> 80 
BEGIN 

    SELECT @DBCompatibilityLevelMajor = @DBCompatibilityLevel/10, 
      @DBCompatibilityLevelMinor = @DBCompatibilityLevel % 10 

    PRINT N' 
    =========================================================================== 
    WARNING! 
    --------------------------------------------------------------------------- 

    This script is designed for Microsoft SQL Server 2000 (8.0) but your 
    database is set up for compatibility with version ' 
    + CAST(@DBCompatibilityLevelMajor AS NVARCHAR(80)) 
    + N'.' 
    + CAST(@DBCompatibilityLevelMinor AS NVARCHAR(80)) 
    + N'. Although 
    the script should work with later versions of Microsoft SQL Server, 
    you can ensure compatibility by executing the following statement: 

    ALTER DATABASE [' 
    + DB_NAME() 
    + N'] 
    SET COMPATIBILITY_LEVEL = 80 

    If you are hosting ELMAH in the same database as your application 
    database and do not wish to change the compatibility option then you 
    should create a separate database to host ELMAH where you can set the 
    compatibility level more freely. 

    If you continue with the current setup, please report any compatibility 
    issues you encounter over at: 

    http://code.google.com/p/elmah/issues/list 

    =========================================================================== 
' 
END 
GO 

/* ------------------------------------------------------------------------ 
     TABLES 
    ------------------------------------------------------------------------ */ 

CREATE TABLE [dbo].[ELMAH_Error] 
(
    [ErrorId]  UNIQUEIDENTIFIER NOT NULL, 
    [Application] NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, 
    [Host]  NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, 
    [Type]  NVARCHAR(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, 
    [Source]  NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, 
    [Message]  NVARCHAR(500) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, 
    [User]  NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL, 
    [StatusCode] INT NOT NULL, 
    [TimeUtc]  DATETIME NOT NULL, 
    [Sequence] INT IDENTITY (1, 1) NOT NULL, 
    [AllXml]  NTEXT COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL 
) 
ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[ELMAH_Error] WITH NOCHECK ADD 
    CONSTRAINT [PK_ELMAH_Error] PRIMARY KEY NONCLUSTERED ([ErrorId]) ON [PRIMARY] 
GO 

ALTER TABLE [dbo].[ELMAH_Error] ADD 
    CONSTRAINT [DF_ELMAH_Error_ErrorId] DEFAULT (NEWID()) FOR [ErrorId] 
GO 

CREATE NONCLUSTERED INDEX [IX_ELMAH_Error_App_Time_Seq] ON [dbo].[ELMAH_Error] 
(
    [Application] ASC, 
    [TimeUtc]  DESC, 
    [Sequence]  DESC 
) 
ON [PRIMARY] 
GO 

/* ------------------------------------------------------------------------ 
     STORED PROCEDURES              
    ------------------------------------------------------------------------ */ 

SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_NULLS ON 
GO 

CREATE PROCEDURE [dbo].[ELMAH_GetErrorXml] 
(
    @Application NVARCHAR(60), 
    @ErrorId UNIQUEIDENTIFIER 
) 
AS 

    SET NOCOUNT ON 

    SELECT 
     [AllXml] 
    FROM 
     [ELMAH_Error] 
    WHERE 
     [ErrorId] = @ErrorId 
    AND 
     [Application] = @Application 

GO 
SET QUOTED_IDENTIFIER OFF 
GO 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_NULLS ON 
GO 

CREATE PROCEDURE [dbo].[ELMAH_GetErrorsXml] 
(
    @Application NVARCHAR(60), 
    @PageIndex INT = 0, 
    @PageSize INT = 15, 
    @TotalCount INT OUTPUT 
) 
AS 

    SET NOCOUNT ON 

    DECLARE @FirstTimeUTC DATETIME 
    DECLARE @FirstSequence INT 
    DECLARE @StartRow INT 
    DECLARE @StartRowIndex INT 

    SELECT 
     @TotalCount = COUNT(1) 
    FROM 
     [ELMAH_Error] 
    WHERE 
     [Application] = @Application 

    -- Get the ID of the first error for the requested page 

    SET @StartRowIndex = @PageIndex * @PageSize + 1 

    IF @StartRowIndex <= @TotalCount 
    BEGIN 

     SET ROWCOUNT @StartRowIndex 

     SELECT 
      @FirstTimeUTC = [TimeUtc], 
      @FirstSequence = [Sequence] 
     FROM 
      [ELMAH_Error] 
     WHERE 
      [Application] = @Application 
     ORDER BY 
      [TimeUtc] DESC, 
      [Sequence] DESC 

    END 
    ELSE 
    BEGIN 

     SET @PageSize = 0 

    END 

    -- Now set the row count to the requested page size and get 
    -- all records below it for the pertaining application. 

    SET ROWCOUNT @PageSize 

    SELECT 
     errorId  = [ErrorId], 
     application = [Application], 
     host  = [Host], 
     type  = [Type], 
     source  = [Source], 
     message  = [Message], 
     [user]  = [User], 
     statusCode = [StatusCode], 
     time  = CONVERT(VARCHAR(50), [TimeUtc], 126) + 'Z' 
    FROM 
     [ELMAH_Error] error 
    WHERE 
     [Application] = @Application 
    AND 
     [TimeUtc] <= @FirstTimeUTC 
    AND 
     [Sequence] <= @FirstSequence 
    ORDER BY 
     [TimeUtc] DESC, 
     [Sequence] DESC 
    FOR 
     XML AUTO 

GO 
SET QUOTED_IDENTIFIER OFF 
GO 
SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 
SET ANSI_NULLS ON 
GO 

CREATE PROCEDURE [dbo].[ELMAH_LogError] 
(
    @ErrorId UNIQUEIDENTIFIER, 
    @Application NVARCHAR(60), 
    @Host NVARCHAR(30), 
    @Type NVARCHAR(100), 
    @Source NVARCHAR(60), 
    @Message NVARCHAR(500), 
    @User NVARCHAR(50), 
    @AllXml NTEXT, 
    @StatusCode INT, 
    @TimeUtc DATETIME 
) 
AS 

    SET NOCOUNT ON 

    INSERT 
    INTO 
     [ELMAH_Error] 
     (
      [ErrorId], 
      [Application], 
      [Host], 
      [Type], 
      [Source], 
      [Message], 
      [User], 
      [AllXml], 
      [StatusCode], 
      [TimeUtc] 
     ) 
    VALUES 
     (
      @ErrorId, 
      @Application, 
      @Host, 
      @Type, 
      @Source, 
      @Message, 
      @User, 
      @AllXml, 
      @StatusCode, 
      @TimeUtc 
     ) 

GO 
SET QUOTED_IDENTIFIER OFF 
GO 
SET ANSI_NULLS ON 
GO 

मैं स्वचालित रूप से इस कोड निष्पादित? मैं db.Database.ExecuteSqlCommand का उपयोग करने की कोशिश की, लेकिन मैं फार्म की त्रुटियों के बहुत सारे मिल:

Incorrect syntax near 'GO'. 
Incorrect syntax near the keyword 'ALTER'. 
Incorrect syntax near the keyword 'ALTER'. 
Incorrect syntax near 'GO'. 
Incorrect syntax near the keyword 'SET'. 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
Must declare the scalar variable "@ErrorId". 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
Must declare the scalar variable "@TotalCount". 
Must declare the scalar variable "@PageIndex". 
Must declare the scalar variable "@TotalCount". 
Must declare the scalar variable "@Application". 
Must declare the scalar variable "@PageSize". 
Must declare the scalar variable "@PageSize". 
Must declare the scalar variable "@Application". 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
Must declare the scalar variable "@ErrorId". 
Incorrect syntax near 'GO'. 
Incorrect syntax near 'GO'. 
+1

क्या यह एल्मा डीबी को एक अलग डीबी में स्थानांतरित करने के लिए एक बड़ी परेशानी होगी ??इस तरह, आपको हर बार अपने सभी लॉग इन ईवेंट खोने की परेशानी नहीं होती है। web.config –

+0

elmah में केवल एक अतिरिक्त कनेक्शनस्ट्रिंग जोड़ने के रूप में सरल केवल हिमशैल का शीर्ष है। मेरे पास स्थैतिक डेटाबेस के लिए अन्य स्क्रिप्ट हैं। – Mediator

+0

ठीक है, मुझे लगता है कि मैं क्या कह रहा हूं कि निश्चित रूप से यहां सबसे अच्छा अभ्यास यह होगा कि केवल आपका कोड पहला डीबी इस सब से प्रभावित होता है (यानी मॉडल बदलने पर डीबी का मनोरंजन)। उस से संबंधित सभी अन्य टेबल एक अनुप्रयोग सेवा डीबी या इसी तरह के होना चाहिए। यह निश्चित रूप से हम अपनी दुकान में यह कैसे करते हैं। –

उत्तर

18

इस माइग्रेशन को आजमाएं, यह ध्यान में रखते हुए कि यह सभी गो बयान एक पंक्ति पर होने की अपेक्षा करता है और फ़ाइल \ r \ n लाइन समाप्ति का उपयोग करती है। मैंने elmah.sqlserver NuGet पैकेज का उपयोग करके एल्मा स्थापित किया, जो उपयुक्त स्थान पर SqlServer.sql फ़ाइल को छोड़ देता है। आपको अपनी परियोजना से मेल खाने के लिए संसाधन नाम बदलने की आवश्यकता होगी।

public partial class Elmah : DbMigration 
{ 
    public override void Up() 
    { 
     var sqlStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MyProject.App_Readme.Elmah.SqlServer.sql"); 
     using(var sqlStreamReader = new StreamReader(sqlStream)) 
     { 
      string sqlScript = sqlStreamReader.ReadToEnd(); 
      ExecuteSqlScript(sqlScript); 
     } 
    } 

    void ExecuteSqlScript(string sqlScript) 
    { 
     string[] sql = sqlScript.Split(new[] {"\r\nGO\r\n"}, StringSplitOptions.RemoveEmptyEntries); 

     foreach (var sqlCommand in sql) 
     { 
      if (!string.IsNullOrWhiteSpace(sqlCommand)) 
       Sql(sqlCommand); 
     } 
    } 

    public override void Down() 
    { 
     DropTable("ELMAH_Error"); 
     Sql("DROP PROCEDURE ELMAH_GetErrorXml"); 
     Sql("DROP PROCEDURE ELMAH_GetErrorsXml"); 
     Sql("DROP PROCEDURE ELMAH_LogError"); 
    } 
} 

मैं

+1

इसे काम करने के लिए मुझे स्क्रिप्ट की बिल्ड एक्शन को "एम्बेडेड रिसोर्स" में बदलने की आवश्यकता है, जैसा कि यहां वर्णित है: http://stackoverflow.com/questions/3068736/cant-load-a-manifest- संसाधन-साथ-getmanifestresourcestream महान जवाब हालांकि, धन्यवाद। –

+0

मैं इस नए मैन्युअल रूप से बनाए गए माइग्रेशन के साथ डीबी को कैसे अपडेट कर सकता हूं? जब मैं 'अद्यतन-डेटाबेस' निष्पादित करता हूं, तो मुझे यह मिलता है: "निर्दिष्ट लक्ष्य माइग्रेशन 'एल्माह' मौजूद नहीं है। सुनिश्चित करें कि लक्ष्य माइग्रेशन मौजूदा माइग्रेशन आईडी को संदर्भित करता है" – ofirbt

+0

मैंने केवल SQL के साथ एक स्ट्रिंग का उपयोग किया (इसलिए नहीं रखा यह एक अलग फाइल में)। \ R \ n हटा दिया गया और यह बहुत अच्छा काम कर रहा है। बहुत धन्यवाद। – ssanchezz23

0

यह GO कथन से अलग SQL कमांड की एक श्रृंखला (सख्ती से T-SQL आदेश नहीं किया जाता है) है

आप स्क्रिप्ट निष्पादित करने के लिए एसक्यूएल मैनेजमेंट स्टूडियो का उपयोग कर सकते हैं, या कमांड लाइन टूल SQLCMD.exe

0

मुझे नहीं लगता कि आपको ExecuteSqlCommand पर कई बैचों को चलाना चाहिए।

आप इसे एसएसएमएस पर क्यों निष्पादित नहीं करते हैं?

+0

मुझे समझ में नहीं आया कि आप – Mediator

0

आपको अपनी स्क्रिप्ट को पार्स करने की आवश्यकता होगी, इसे SQL कमांड को अलग करने के लिए विभाजित करें और SqlCommand के माध्यम से उनमें से प्रत्येक को निष्पादित करें। दुर्भाग्यवश, मुझे इसे स्वचालित करने के तरीके से अवगत नहीं है।

0

स्क्रिप्ट आपको बैचों को अलग करने की आवश्यकता है (GO बैच विभाजक है) और प्रत्येक बैच को व्यक्तिगत रूप से SQL सर्वर पर भेजें। मेरे पास वास्तव में एक नमूना प्रोजेक्ट dbutilsqlcmd है जो कि बस करता है, और स्क्रिप्ट में :setvar और $(variable) प्रतिस्थापन जैसे एसक्यूएलसीएमडी एक्सटेंशन का भी समर्थन करता है, जो तैनाती पर काफी उपयोगी हो सकता है।

4

ओपी को उत्तर के रूप में मेरी टिप्पणी को औपचारिक रूप देने के लिए;

मुझे लगता है कि यहां सबसे अच्छा अभ्यास यह होगा कि केवल आपका कोड-पहला डीबी किसी भी कट्टरपंथी परिवर्तन से प्रभावित होना चाहिए (यानी मॉडल बदलने पर डीबी का मनोरंजन)। उस से संबंधित सभी अन्य टेबल एक अनुप्रयोग सेवा डीबी या समान में होना चाहिए और कोर डीबी में नहीं होना चाहिए। इस तरह आप हर बार एक साधारण संपत्ति या डेटा प्रकार परिवर्तन के साथ अपने मॉडल को अद्यतन करने की आवश्यकता होने पर एक समर्थन दुःस्वप्न नहीं बनाते हैं। इसके अलावा, आप निश्चित रूप से परिवर्तन करते समय अपने लॉगिंग (और अन्य) डीबी टेबल के पूरे इतिहास को खो देते हैं।

तो, एक शब्द में, मुझे लगता है कि आप एक संभावित अनुचित समाधान के साथ गलत समस्या का सामना कर रहे हैं।

यह निश्चित रूप से हम अपनी दुकान में और पिछली परियोजनाओं में करते हैं जो मैंने काम किया है।

+0

चीयर्स डेनिस !! :) एक grt सप्ताहांत है –

0

अब एक nuget पैकेज है कि आप के लिए Elmah मेज और procs प्रारंभ हो जाएगा है: https://www.nuget.org/packages/Elmah.SqlServer.EFInitializer/। इसे अपने वेब प्रोजेक्ट में जोड़ें। इसके बाद यह आपके लिए इसे बनाने के लिए पहले ईएफ कोड का उपयोग करेगा। यह आपके App_Start फ़ोल्डर में एक प्रारंभकर्ता जोड़ता है ताकि आपको वास्तव में कोई कोड जोड़ने की आवश्यकता न हो। यह सुनिश्चित करने के लिए कि यह केवल एक बार जोड़ा जाता है, यह आपके डेटाबेस में माइग्रेशन जोड़ देगा।

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