使用Linq to Entity查找基础视图表以生成聚合依赖项

时间:2011-11-14 13:27:43

标签: c# asp.net linq entity-framework sqlcachedependency

我有一个功能:

 public static List<T> EntityCache<T>(this System.Linq.IQueryable<T> q, ObjectContext dc, string CacheId)
    {


        try
        {
            List<T> objCache = (List<T>)System.Web.HttpRuntime.Cache.Get(CacheId);

            string connStr = (dc.Connection as System.Data.EntityClient.EntityConnection).StoreConnection.ConnectionString;

            if (objCache == null)
            {
                ObjectQuery<T> productQuery = q as ObjectQuery<T>;

                string sqlCmd = productQuery.ToTraceString();

                using (System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr))
                {
                    conn.Open();
                    using (System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sqlCmd, conn))
                    {

                        string NotificationTable = q.ElementType.Name;
                        System.Web.Caching.SqlCacheDependency sqldep = new System.Web.Caching.SqlCacheDependency(cmd);
                        cmd.ExecuteNonQuery();
                        objCache = q.ToList();
                        System.Web.HttpRuntime.Cache.Insert(CacheId, objCache, sqldep);
                    }
                }
            }

            return objCache;

        }
        catch (Exception ex)
        {
            throw ex;
        }

    }

q可以是表格,视图或程序。

我想要的是找到与视图或过程关联的基础表。

如果q是两个表的连接,我想得到两个表的名称,最后

执行如下:

如果有两张表说A和B

然后我需要像以下那样进行聚合依赖:

  string sqlCmd1 = string.Empty;
                        string sqlCmd2 = string.Empty;

                        using (testEntities ctx1 = new testEntities())
                        {
                            sqlCmd1 = ((System.Data.Objects.ObjectQuery)(from p in ctx1.A select p)).ToTraceString();
                            sqlCmd2 = ((System.Data.Objects.ObjectQuery)(from p in ctx1.B select p)).ToTraceString();
                        }

                        System.Data.SqlClient.SqlCommand cmd1 = new System.Data.SqlClient.SqlCommand(sqlCmd1, conn);
                        System.Data.SqlClient.SqlCommand cmd2 = new System.Data.SqlClient.SqlCommand(sqlCmd2, conn);


 System.Web.Caching.SqlCacheDependency
                       dep1 = new System.Web.Caching.SqlCacheDependency(cmd1),
                       dep2 = new System.Web.Caching.SqlCacheDependency(cmd2);

                        System.Web.Caching.AggregateCacheDependency aggDep = new System.Web.Caching.AggregateCacheDependency();
                        aggDep.Add(dep1, dep2);

                        cmd1.ExecuteNonQuery();
                        cmd2.ExecuteNonQuery();

然后我要执行的查询是

从A中选择*; 从B中选择*;

这是我使用Linq to Entity的SqlCacheDependency。

当我对基础表进行硬编码时,它适用于视图,但现在我希望代码自动检查基础表

并执行非查询,如

   cmd1.ExecuteNonQuery();
   cmd2.ExecuteNonQuery();

并制作聚合依赖项。

感谢任何帮助。

感谢。

2 个答案:

答案 0 :(得分:1)

您必须使用数据库级工具来查找视图或存储过程所依赖的数据库对象(但这也意味着您必须知道数据库中的全名)。例如,SQL Server提供sp_depends系统存储过程来跟踪依赖关系。这可能非常复杂,因为依赖关系可以有多个级别(过程可以依赖于视图,视图可以依赖于另一个视图等)。

请注意,高级EF映射还允许将SQL直接写入EDMX,在这种情况下,您必须解析ToTraceString以查找数据库对象。

答案 1 :(得分:0)

我找到了解决我发布的问题的解决方案。

有一个查询对sql server 2005以后有效。

我们需要传递对象的名称,它将返回它所依赖的表的名称

示例:

视图的名称是 AllProducts_Active_Inactive

                 ;WITH CTE AS (SELECT   o.name
            ,       o.type_desc 
            ,       p.name
            ,       p.type_desc as B
            ,       p.object_id
            FROM    sys.sql_dependencies d
                    INNER JOIN sys.objects o
                    ON d.object_id = o.object_id
                    INNER JOIN sys.objects p
                    ON d.referenced_major_id = p.object_id

                    where o.name = 'AllProducts_Active_Inactive'

            UNION ALL
            SELECT  o.name
            ,       o.type_desc 
            ,       p.name
            ,       p.type_desc as B
            ,       p.[object_id]
            FROM    sys.sql_dependencies d
                    INNER JOIN CTE o
                    ON d.object_id = o.object_id
                    INNER JOIN sys.objects p
                    ON d.referenced_major_id = p.object_id

                    where o.name = 'AllProducts_Active_Inactive'

                   ) 
            SELECT DISTINCT * FROM [CTE]
            where B = 'USER_TABLE'

这篇文章是我在网站上发布的问题的修改后的答案:

http://ask.sqlservercentral.com/questions/81318/find-the-underlying-tables-assocaited-with-a-view-or-a-stored-procedure-in-sql-server

我更改的内容添加了 B ='USER_TABLE'

的行

这意味着只返回那些属于表的依赖项。

并且秒的内容添加了 WHERE 子句,以便找到特定的对象。

由于