LocalDB中的SQLCLR触发/过程?

时间:2013-12-20 22:24:37

标签: c# sqlclr entity-framework-6 localdb

我正在努力让SQL CLR程序与LocalDB(2012)一起使用。我的触发器和程序(下面)永远不会被调用。我正在使用Entity Framework 6创建LocalDB。触发器应该在这种情况下工作吗?

using System;
using System.Data;
using System.Data.Entity;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using Dapper;

namespace TestSqlCallback
{
    class Program
    {
        public class MyEntity
        {
            public long Id { get; set; }
            public string Value { get; set; }
        }

        public class MyContext: DbContext
        {
            static MyContext()
            {
                AppDomain.CurrentDomain.SetData("DataDirectory", Path.GetTempPath());
                Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
            }

            public DbSet<MyEntity> Entities { get; set; }
        }

        static void Main(string[] args)
        {
            var context = new MyContext();
            var count = context.Entities.Count();

            Console.WriteLine("Starting with {0} entities.", count);

            var con = context.Database.Connection;
            con.Execute("sp_configure 'clr enabled', 1;");
            con.Execute("reconfigure");
            con.Execute("CREATE ASSEMBLY [TestSqlCallbackTriggers] from '" + typeof(Triggers.MySqlClr).Assembly.Location + "';");
            con.Execute(@"CREATE TRIGGER TestTrigger ON [dbo].[MyEntities] FOR INSERT, UPDATE, DELETE 
                                        AS EXTERNAL NAME TestSqlCallbackTriggers.[TestSqlCallback.Triggers.MySqlClr].TestTrigger;");
            con.Execute(@"CREATE PROCEDURE TestProcedure AS EXTERNAL NAME TestSqlCallbackTriggers.[TestSqlCallback.Triggers.MySqlClr].TestProcedure;");

            context.Entities.Add(new MyEntity {Value = "be cool"});

            var sw = Stopwatch.StartNew();
            con.Execute("TestProcedure", commandType: CommandType.StoredProcedure);
            context.SaveChanges();
            count = context.Entities.Count();
            Console.WriteLine("Ending with {0} entities. Waiting for trigger...", count);
            SpinWait.SpinUntil(() => Triggers.MySqlClr.Workaround.Value > 1);
            Console.WriteLine("Finised in {0}ms", sw.Elapsed.TotalMilliseconds);

            if (Debugger.IsAttached)
                Console.ReadKey();
        }
    }
}

其他项目中具有较少依赖项的其他文件:

using System.Threading;
using Microsoft.SqlServer.Server;

namespace TestSqlCallback.Triggers
{
    public class MySqlClr
    {
        public class Wrapper<T>
        {
            public T Value;
        }

        public readonly static Wrapper<int> Workaround = new Wrapper<int>();

        //[SqlTrigger(Name = "TestTrigger", Event = "FOR INSERT, UPDATE, DELETE", Target = "[dbo].[MyEntities]")]
        //[SqlTrigger] // doesn't work with or without
        public static void TestTrigger()
        {
            var context = SqlContext.TriggerContext;
            if (context == null) return;

            switch (context.TriggerAction)
            {
                case TriggerAction.Insert:
                    Interlocked.Increment(ref Workaround.Value);
                    break;
                case TriggerAction.Update:
                    break;
                case TriggerAction.Delete:
                    break;
                default:
                    return;
            }
        }

        //[SqlProcedure]
        public static void TestProcedure()
        {
            var context = SqlContext.TriggerContext;
            if (context == null) return;
            Interlocked.Increment(ref Workaround.Value);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我尝试了同样的事情,最终只使用了一个SqlDataReader。无论如何,我需要在app.config文件中放入正确的连接字符串。

参考文献如下:

 <connectionStrings>
    <add name="MyAwesomeDBEntities" connectionString="metadata=res://*/MyAwesomeDBLocalDB.csdl|res://*/MyAwesomeDBLocalDB.ssdl|res://*/MyAwesomeDBLocalDB.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=np:\\.\pipe\LOCALDB#C1AA2FB7\tsql\query;initial catalog=MyAwesomeDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

为此,我需要在从命令行启动数据库后更新连接字符串的数据源部分。

我跑了&#34; sqllocaldb.exe信息&#34;在命令提示符下获取实例名称。在我的情况下,我运行&#34; sqllocaldb.exe信息v11.0&#34; (运行&#34; sqllocaldb.exe启动v11.0&#34;)并比较&#34;实例管道名称&#34;对数据源的价值&#34;连接字符串的一部分。

如果仍然无效,我会更新我的回答以提供更多信息。