0

복합 기본 키가있는 테이블에 DbSyncForeignKeyConstraint를 만들려고하지만 오류가 계속 발생합니다.복합 기본 키가있는 테이블에 DbSyncForeignKeyConstraint를 만드는 방법

예를 들어 테이블 : 여기에 내가 뭐하는 거지 설명하는 몇 가지 샘플 코드 여기

USE [TempTest] 
GO 

CREATE TABLE [dbo].[Users](
     [UserId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
    (
     [UserId] ASC 
    ) 
    WITH 
    (
     PAD_INDEX = OFF, 
     STATISTICS_NORECOMPUTE = OFF, 
     IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, 
     ALLOW_PAGE_LOCKS = ON 
    ) ON [PRIMARY] 
) ON [PRIMARY] 

CREATE TABLE [dbo].[UsersRoles](
    [UserId] [uniqueidentifier] NOT NULL, 
    [RoleId] [uniqueidentifier] NOT NULL, 
    CONSTRAINT [PK_UsersRoles] PRIMARY KEY CLUSTERED 
    (
     [UserId] ASC, 
     [RoleId] ASC 
    ) 
    WITH 
    (
     PAD_INDEX = OFF, 
     STATISTICS_NORECOMPUTE = OFF, 
     IGNORE_DUP_KEY = OFF, 
     ALLOW_ROW_LOCKS = ON, 
     ALLOW_PAGE_LOCKS = ON 
    ) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

및 내 C# 코드 : 위의 코드는이 오류를 생성 할

DbSyncTableDescription tableDesc = SqlSyncDescriptionBuilder.GetDescriptionForTable("UsersRoles", (SqlConnection)this.dbProvider.Connection); 
Collection<string> parentkeys = new Collection<string>(); 
parentkeys.Add("UserId"); 
Collection<string> childkeys = new Collection<string>(); 
childkeys.Add("RoleId"); 
childkeys.Add("UserId"); 
tableDesc.Constraints.Add(new DbSyncForeignKeyConstraint("FK_UsersRoles_Users", "Users", "UsersRoles", parentkeys, childkeys)); 

:

The definition of referring columns (such as number of columns or data types) in referential relationships must match the referred columns.

줄을 childkeys.Add("RoleId")으로 주석 처리하면 다음 오류가 표시됩니다. "참조 된 테이블에 기본 키 또는 후보 키가 있어야합니다."

그래서 내가 어떻게해야하는지에 대해서는 조금 분명하지 않습니다. 제약 조건은 실제로이 예에서 UserId 열에 관한 것입니다. 그러나 UsersRoles 테이블에는 복합 기본 키가 있으므로 제약 조건에 포함해야합니까? 제약 조건 정의에서 "RoleId"를 생략하면 오류가 발생합니다 ... 포함 시키면 다른 오류가 발생합니다.

진행 방법에 대한 제안이있는 사람이 있습니까? (PS : 기본 키가 아닌 기본 키가있는 테이블간에 다른 외래 키를 만드는 코드가 있으며이 코드는 오류없이 작동합니다.

편집 추가 정보 : 확인. 문제는 DBSyncForeignKeyConstraint 생성과 관련이없는 것처럼 보입니다. 문제가있는 GetDescriptionForTable 기능을 것 같습니다. 기본 키처럼 UserId를 선택하지 않는 것 같습니다. 내 프로젝트에서 실제로 aspnet_Membership 스키마를 사용하는 데이터베이스에 대해 작업하고 있습니다. 그래서, 스크립트 경우 aspnet_Users 테이블, 그것은 다음과 같습니다, 내가보고 내가 "GetScopeDescription"을 호출의 결과를 살펴보면, ' CREATE TABLE [dbo].[aspnet_Users](
[ApplicationId] [uniqueidentifier] NOT NULL,
[UserId] [uniqueidentifier] NOT NULL,
[UserName] nvarchar NOT NULL,
[LoweredUserName] nvarchar NOT NULL,
[MobileAlias] nvarchar NULL,
[IsAnonymous] [bit] NOT NULL,
[LastActivityDate] [datetime] NOT NULL, PRIMARY KEY NONCLUSTERED ( [UserId] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]

GO

ALTER TABLE [dbo].[aspnet_Users] WITH CHECK ADD FOREIGN KEY([ApplicationId]) REFERENCES [dbo].[aspnet_Applications] ([ApplicationId]) GO
ALTER TABLE [dbo].[aspnet_Users] ADD DEFAULT (newid()) FOR [UserId]
GO
ALTER TABLE [dbo].[aspnet_Users] ADD DEFAULT (NULL) FOR [MobileAlias]
GO
ALTER TABLE [dbo] [aspnet_Users] ADD DEFAULT ((0)) FOR [IsAnonymous] GO'

을하지만 "LoweredUserName는"PKColumns로 표시되는 열 "애플리케이션 ID"및 및 그 UserId는 NonPkColumns 중에 나열됩니다. 나는 이것이 무엇을 일으키는 지 전혀 모른다. 그러나 적어도 "UserId"열이 기본 키 사이에 없다는 오류가 나오는 이유를 이해합니다. 데이터베이스에 있지만 GetScopDescription의 결과에는 없습니다. 그래서 나는 최소한 검색을 시작하는 방향을 알고 있습니다.

+0

덕분에 ... 나는 코드가 제대로 포맷하지 않았는지 모르겠습니다. 나는 그것을보기 좋게하기 위해 여러 번 노력했다. – rogdawg

답변

0

당신이 코드를 프로비저닝하고 어떻게하지 않도록이처럼 보이지만이

 var sqlConn = new SqlConnection(@"Data Source=(local)\SQLExpress; Initial Catalog=Test; Integrated Security=True"); 
     var sqlConn2 = new SqlConnection(@"Data Source=(local)\SQLExpress; Initial Catalog=Test2; Integrated Security=True"); 

     var parent = SqlSyncDescriptionBuilder.GetDescriptionForTable("Users", sqlConn); 
     var child = SqlSyncDescriptionBuilder.GetDescriptionForTable("UsersRoles", sqlConn); 

     var parentPKColumns = new Collection<string> {"UserId"}; 
     var childFKColumns = new Collection<string> {"UserId"}; 

     child.Constraints.Add(new DbSyncForeignKeyConstraint("FK_UsersRoles_Users", "Users", "UsersRoles", parentPKColumns, childFKColumns)); 

     var fKTestScope= new DbSyncScopeDescription("FKTestScope"); 

     fKTestScope.Tables.Add(parent); 
     fKTestScope.Tables.Add(child); 

     var scopeProvisioning = new SqlSyncScopeProvisioning(sqlConn2, fKTestScope); 

     scopeProvisioning.Apply(); 
+0

놀라운. 내가 사용하고있는 코드와 내가 제공 한 예제 (명확성을 위해) 사이에서 볼 수있는 유일한 차이점은 실제 테이블에서 기본 테이블 키가 클러스터되지 않고 위의 예제 코드에서 클러스터된다는 것입니다. 나는 클러스터되지 않은 기본 키에 외래 키 제약 조건을 생성하는 몇 가지 인스턴스를 가지고 있으므로 실제로 이것이 문제라고 생각하지 않습니다. 내 실제 코드에서 aspnet_Membership 스키마를 사용하여 데이터베이스에 동기화하려고 시도하고 있으며이 제약 조건은 aspnet_UsersInRoles와 aspnet_Users (aspnet_UsersInRoles 및 aspent_Roles) 사이에 있습니다. 나는 계속 노력할 것이다. – rogdawg

+0

그건 그렇고, Sync Framework 2.1을 사용하고 있습니다. – rogdawg

+0

"추가 정보로 수정 : 확인"을 클릭 한 후 원래 게시물을 참조하십시오. 고맙습니다. – rogdawg

0

OK 완벽하게 잘 작동,이 범위 프로비저닝 기능을 가진 매우 심각한 문제가 될 것으로 보인다. 내가 프로비저닝 된 내 소스 데이터베이스로 이동하여 scope_config 테이블의 config_data 열에서 데이터를 보면, 나는 aspnet_Users 테이블이 잘못된 방식으로 설명된다, XML에서, 참조 :

<Adapter Name="[aspnet_Users]" GlobalName="[aspnet_Users]" TrackingTable="[aspnet_Users_tracking]" SelChngProc="[aspnet_Users_selectchanges]" SelRowProc="[aspnet_Users_selectrow]" InsProc="[aspnet_Users_insert]" UpdProc="[aspnet_Users_update]" DelProc="[aspnet_Users_delete]" InsMetaProc="[aspnet_Users_insertmetadata]" UpdMetaProc="[aspnet_Users_updatemetadata]" DelMetaProc="[aspnet_Users_deletemetadata]" BulkTableType="[aspnet_Users_BulkType]" BulkInsProc="[aspnet_Users_bulkinsert]" BulkUpdProc="[aspnet_Users_bulkupdate]" BulkDelProc="[aspnet_Users_bulkdelete]" InsTrig="[aspnet_Users_insert_trigger]" UpdTrig="[aspnet_Users_update_trigger]" DelTrig="[aspnet_Users_delete_trigger]"> 
<Col name="ApplicationId" type="uniqueidentifier" param="@P_1" pk="true" /> 
<Col name="UserId" type="uniqueidentifier" param="@P_2" /> 
<Col name="UserName" type="nvarchar" size="256" param="@P_3" /> 
<Col name="LoweredUserName" type="nvarchar" size="256" param="@P_4" pk="true" /> 
<Col name="MobileAlias" type="nvarchar" size="16" null="true" param="@P_5" /> 
<Col name="IsAnonymous" type="bit" param="@P_6" /> 
<Col name="LastActivityDate" type="datetime" param="@P_7" /> 

ApplicationId 및 LoweredUserName 열이 pks로 표시되어 있지 않은 경우 확인할 수 있습니다. 그리고 UserId 열은 반드시 있어야 할 때 pk로 표시되지 않습니다. 이 잘못된 데이터로 인해 aspnet_Users 테이블에 대해 생성 된 추적 테이블이 잘못 구성되어 xml을 scope_config 테이블에 수정하는 것만으로는 문제를 해결할 수 없습니다.그래서, 나는 큰 문제를 바로 잡아서 올바른 것을 취하는 것처럼 보일 것입니다. 서버 구성을 수행 할 때 매개 변수를 설정하지 않으므로이 오류를 작성하는 데 아무 것도하지 않는다고 생각합니다.

다른 곳에서는이 문제에 대한 설명을 찾을 수 없었지만 실제로는 이상하게 보입니다.하지만 계속 찾아 보겠습니다.

어!

SQL Server Management Studio에 탐색기의 이미지가 포함됩니다.

도움을 주신 JunT 님, 감사합니다.

enter image description here

0

이 테이블 구조를 잡기 위해 동기화 FX는 내부적으로 사용으로 인해의 DataReader가에 GetSchemaTable처럼 보인다 (참조 : http://social.msdn.microsoft.com/Forums/en-US/adodotnetdataproviders/thread/c1c113e2-32dc-4826-b6e0-17dff29c1baf)

을 해결 방법으로, 단지 PK 자신을 설정합니다.

예를 들어, 편집을위한

downloadOnlyScopeDesc.Tables.Add(SqlSyncDescriptionBuilder.GetDescriptionForTable("aspnet_Users", (System.Data.SqlClient.SqlConnection)provider.Connection)); 

//untag wrong PK information 
foreach(var pkColumn in downloadOnlyScopeDesc.Tables["aspnet_Users"].PkColumns) 
{ 
    downloadOnlyScopeDesc.Tables["aspnet_Users"].Columns[pkColumn.QuotedName].IsPrimaryKey = false; 
} 

//tag the correct PK 
downloadOnlyScopeDesc.Tables["aspnet_Users"].Columns["UserId"].IsPrimaryKey = true; 
관련 문제