C# SQL Server:ADO.Net GetUpdateCommand和ok with PK在添加另一个聚集唯一索引后失败
我有这样一个带有非聚集主键的表:C# SQL Server:ADO.Net GetUpdateCommand和ok with PK在添加另一个聚集唯一索引后失败,c#,.net,sql-server,ado.net,clustered-index,C#,.net,Sql Server,Ado.net,Clustered Index,我有这样一个带有非聚集主键的表: CREATE TABLE [dbo].[StudentGrade]( [EnrollmentID] [int] IDENTITY(1,1) NOT NULL, [CourseID] [nvarchar](10) NOT NULL, [StudentID] [int] NOT NULL, [Grade] [decimal](3, 2) NOT NULL, CONSTRAINT [PK_StudentGrade] PRIMARY KE
CREATE TABLE [dbo].[StudentGrade](
[EnrollmentID] [int] IDENTITY(1,1) NOT NULL,
[CourseID] [nvarchar](10) NOT NULL,
[StudentID] [int] NOT NULL,
[Grade] [decimal](3, 2) NOT NULL,
CONSTRAINT [PK_StudentGrade] PRIMARY KEY NONCLUSTERED ([EnrollmentID] ASC))
select语句是:
select EnrollmentID,Grade from StudentGrade
GetUpdateCommand工作正常,可以识别非集群主键
添加另一个聚集唯一索引时(在两列上,甚至不是select子句的一部分):
GetUpdateCommand失败,出现以下异常:
System.InvalidOperationException: Dynamic SQL generation for the
UpdateCommand is not supported against a SelectCommand that does not return
any key column information.
如果索引不是唯一的或不是聚集的,则不存在错误
与描述元数据的主键相比,似乎更倾向于使用聚集唯一索引。如果存在多个候选键(pk/unique索引),则不会尝试使用查询中包含所有列的候选键
这是预期的行为吗?除了选择索引列或明确更新命令之外,还有什么简单的修复方法吗
为了提高性能,我需要使用这个聚集索引,主键在查询中并不常用
看起来聚集唯一索引是首选的索引
用于描述元数据的主键
是的,这是问题的关键。您可以使用。在只有非聚集主键的情况下,EnrolmentID列是标识为“is_part_of_unique_key”的列:
在复合自然键列上添加唯一聚集索引后,CourseID和StudentID成为客户端API首选的唯一键。这些作为隐藏的元数据列返回,标记为“is_part_of_unique_key”:
唯一聚集索引是首选的,因为它是用于单例查询的最有效的键。这意味着客户机需要SELECT
查询返回的键值,以便自动生成的CRUD语句正常工作
有几个选项可以避免将自然键列添加到select查询中。一种方法是使用封装查询的view\u METADATA
选项创建视图,并在代码中使用该选项,而不是直接在表中使用该选项:
CREATE VIEW vw_StudentGrade
WITH VIEW_METADATA
AS
SELECT EnrollmentID, Grade from StudentGrade;
然后,元数据被限制为视图返回的列,因此即使有唯一聚集索引(或唯一约束),也会将EnrollmentID
识别为唯一键列:
EXEC sp_describe_first_result_set
@tsql = N'SELECT EnrollmentID,Grade FROM vw_StudentGrade'
, @params = NULL
, @browse_information_mode = 1;
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+----------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+-----------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
| is_hidden | column_ordinal | name | is_nullable | system_type_id | system_type_name | max_length | precision | scale | collation_name | user_type_id | user_type_database | user_type_schema | user_type_name | assembly_qualified_type_name | xml_collection_id | xml_collection_database | xml_collection_schema | xml_collection_name | is_xml_document | is_case_sensitive | is_fixed_length_clr_type | source_server | source_database | source_schema | source_table | source_column | is_identity_column | is_part_of_unique_key | is_updateable | is_computed_column | is_sparse_column_set | ordinal_in_order_by_list | order_by_is_descending | order_by_list_length | tds_type_id | tds_length | tds_collation_id | tds_collation_sort_id |
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+----------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+-----------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
| 0 | 1 | EnrollmentID | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | vw_StudentGrade | EnrollmentID | 1 | 1 | 0 | 0 | 0 | NULL | NULL | NULL | 56 | 4 | NULL | NULL |
| 0 | 2 | Grade | 0 | 106 | decimal(3,2) | 5 | 3 | 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | vw_StudentGrade | Grade | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | 106 | 17 | NULL | NULL |
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+----------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+-----------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
另一个选项是手动创建UpdateCommand
,而不是使用CommandBuilder
。这将为您提供完全控制权,以便您可以在WHERE
子句中使用EnrollmentID
,而不考虑返回的元数据
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+------------------------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+--------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
| is_hidden | column_ordinal | name | is_nullable | system_type_id | system_type_name | max_length | precision | scale | collation_name | user_type_id | user_type_database | user_type_schema | user_type_name | assembly_qualified_type_name | xml_collection_id | xml_collection_database | xml_collection_schema | xml_collection_name | is_xml_document | is_case_sensitive | is_fixed_length_clr_type | source_server | source_database | source_schema | source_table | source_column | is_identity_column | is_part_of_unique_key | is_updateable | is_computed_column | is_sparse_column_set | ordinal_in_order_by_list | order_by_is_descending | order_by_list_length | tds_type_id | tds_length | tds_collation_id | tds_collation_sort_id |
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+------------------------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+--------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
| 0 | 1 | EnrollmentID | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | StudentGrade | EnrollmentID | 1 | 0 | 0 | 0 | 0 | NULL | NULL | NULL | 56 | 4 | NULL | NULL |
| 0 | 2 | Grade | 0 | 106 | decimal(3,2) | 5 | 3 | 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | StudentGrade | Grade | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | 106 | 17 | NULL | NULL |
| 1 | 3 | CourseID | 0 | 231 | nvarchar(10) | 20 | 0 | 0 | SQL_Latin1_General_CP1_CI_AS | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | StudentGrade | CourseID | 0 | 1 | 1 | 0 | 0 | NULL | NULL | NULL | 231 | 20 | 13632521 | 52 |
| 1 | 4 | StudentID | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | StudentGrade | StudentID | 0 | 1 | 1 | 0 | 0 | NULL | NULL | NULL | 56 | 4 | NULL | NULL |
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+------------------------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+--------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
CREATE VIEW vw_StudentGrade
WITH VIEW_METADATA
AS
SELECT EnrollmentID, Grade from StudentGrade;
EXEC sp_describe_first_result_set
@tsql = N'SELECT EnrollmentID,Grade FROM vw_StudentGrade'
, @params = NULL
, @browse_information_mode = 1;
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+----------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+-----------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
| is_hidden | column_ordinal | name | is_nullable | system_type_id | system_type_name | max_length | precision | scale | collation_name | user_type_id | user_type_database | user_type_schema | user_type_name | assembly_qualified_type_name | xml_collection_id | xml_collection_database | xml_collection_schema | xml_collection_name | is_xml_document | is_case_sensitive | is_fixed_length_clr_type | source_server | source_database | source_schema | source_table | source_column | is_identity_column | is_part_of_unique_key | is_updateable | is_computed_column | is_sparse_column_set | ordinal_in_order_by_list | order_by_is_descending | order_by_list_length | tds_type_id | tds_length | tds_collation_id | tds_collation_sort_id |
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+----------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+-----------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+
| 0 | 1 | EnrollmentID | 0 | 56 | int | 4 | 10 | 0 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | vw_StudentGrade | EnrollmentID | 1 | 1 | 0 | 0 | 0 | NULL | NULL | NULL | 56 | 4 | NULL | NULL |
| 0 | 2 | Grade | 0 | 106 | decimal(3,2) | 5 | 3 | 2 | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 0 | 0 | 0 | NULL | tempdb | dbo | vw_StudentGrade | Grade | 0 | 0 | 1 | 0 | 0 | NULL | NULL | NULL | 106 | 17 | NULL | NULL |
+-----------+----------------+--------------+-------------+----------------+------------------+------------+-----------+-------+----------------+--------------+--------------------+------------------+----------------+------------------------------+-------------------+-------------------------+-----------------------+---------------------+-----------------+-------------------+--------------------------+---------------+-----------------+---------------+-----------------+---------------+--------------------+-----------------------+---------------+--------------------+----------------------+--------------------------+------------------------+----------------------+-------------+------------+------------------+-----------------------+