0

我有一个功能:

 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 是两个表的连接,我想获得两个表的名称,最后

执行如下:

如果有 tw0 表说 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();

并建立聚合依赖关系。

任何帮助表示赞赏。

谢谢。

4

2 回答 2

1

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

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

于 2011-11-14T13:51:23.640 回答
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-asocaited-with-a-view-or-a-stored-procedure-in-sql-server

我更改的是添加B = 'USER_TABLE'的行

这意味着只返回那些作为表的依赖项。

第二件事是添加一个WHERE子句,以便找到特定的对象。

谢谢

于 2011-11-17T14:49:10.937 回答