3

データベースの LINQ-to-SQL DataContext とエンティティ クラスを生成しています。データベースにはいくつかのテーブルがあり、そのうちの 2 つは [AccountMaster] と [AccountCodes] です。それらの間には外部キー関係が定義されており、[AccountMaster].AccountNumber は [AccountCodes] から参照されます。

VS2008 で LINQ-to-SQL ファイルを追加し、これらのテーブルを DBML デザイン ビューにドラッグすると、AccountMaster クラス内に AccountNotes のコレクションが適切に生成されます。一方、SQLMetal を使用して DataContext を生成しても、EntitySet コレクションは生成されません。

デザイナーの出力:

[Table(Name="dbo.A01_AccountMaster")]
public partial class A01_AccountMaster //...
{
//...
    private long _AccountNumber;
    private EntitySet<A01aAccountNote> _A01aAccountNotes;
//...
}

SQLMetal 出力:

[Table(Name="dbo.A01_AccountMaster")]
[DataContract()]
public partial class A01_AccountMaster //...
{
//...
    private long _AccountNumber;
//...
}

のガイドに従っています

http://weblogs.asp.net/scottgu/archive/2007/07/11/linq-to-sql-part-4-updating-our-database.aspx

最初に SQLMetal を使用して DBML ファイルを生成し、次に結果の DBML から DataContext.cs ファイルを生成しようとしました。

sqlmetal.exe /server:srv /database:db /user:usr /password:pwd /sprocs /namespace:AccountContext /context:AccountContext /dbml:AccountContext.dbml /language:csharp /serialization:unidirectional
sqlmetal.exe /sprocs /namespace:AccountContext /context:AccountContext /code:AccountContext.cs /language:csharp /serialization:unidirectional AccountContext.dbml

これは関連付けを生成しません。実際、SQLMetal とデザイナー ビューから DBML ファイルを調べると、次のようになります。

デザイン ビュー DBML:

<Type Name="A01_AccountMaster">
<!-- ... -->
<Column Name="AccountNumber" Type="System.Int64" DbType="BigInt NOT NULL" CanBeNull="false" />
<Association Name="A01_AccountMaster_A01aAccountNote" Member="A01aAccountNotes" ThisKey="AccountNumber" OtherKey="AccountNumber" Type="A01aAccountNote" />
<!-- ... -->
</Type>

SQL メタル DBML:

<Type Name="A01_AccountMaster">
<!-- ... -->
<Column Name="AccountNumber" Type="System.Int64" DbType="BigInt NOT NULL" CanBeNull="false" />
<!-- ... -->
</Type>

そのため、関連付けは DBML ステップで既に欠落しています。

データベースには大量のテーブル/sproc が含まれているため、デザイナーを使用して DataContext クラスを再生成するのは現実的ではありません。SQLMetal で関連付けを正しく生成するにはどうすればよいですか?

編集:

データベース全体で SQLMetal を実行すると、一部のエンティティの関連付けが正しく生成されていることがわかりました。AccountNotes の外部キーは次のように定義されます。

ALTER TABLE [dbo].[A01aAccountNotes]  WITH CHECK ADD  CONSTRAINT [FK_A01aAccountNotes_A01_AccountMaster] FOREIGN KEY([AccountNumber])
REFERENCES [dbo].[A01_AccountMaster] ([AccountNumber])
GO

ALTER TABLE [dbo].[A01aAccountNotes] CHECK CONSTRAINT [FK_A01aAccountNotes_A01_AccountMaster]
GO

EDIT2:

正しく作成された関連付けは、ON DELETE CASCADE/UPDATE ルールを持つ関連付けであることに気付きました。このルールがデータベース レベルで厳密に定義されていない関連付けを生成することは無意味ですか?

4

2 に答える 2

3

同様の問題が発生しました。テーブルに冗長インデックスがあり、列に一意の非クラスター化インデックスとして定義されています。これは、既にクラスター化インデックスであるテーブルの主キーです。非クラスター化インデックスを削除しようとすると、SQL Serverは、それに依存する外部キーがあったために抵抗しました。すべての外部キーを削除し、インデックスを削除し、外部キーを再作成する必要がありました(現在は実際のPKに依存します)。その後、SQLMetalは満足しました。

于 2011-04-01T15:36:57.260 に答える
1

SQLMetal にバグがあるか、データベースに矛盾があるようです。

2 つの異なるコードベースであるため、異なる抽出結果が得られます (質問しないでください)。

できることの 1 つは、SQL トレースをオンにして、SqlMetal がデータベースに送信してリストを取得する TSQL DDL コマンドを観察することです。これらは、INFORMATION_SCHEMA クエリとさまざまな結合を組み合わせたものです。

関連付けを表示するために必要な結合の一部が不発になっているようです。SQL Server に送信されたクエリを SQL Management Studio ウィンドウにコピーして実行すると、関連付けが欠落していることがわかります。

それが事実であることを確認したら、一部の結合を LEFT 結合に変えて、どの部分が失敗しているかを確認する (またはいくつかの WHERE 条件を削除する) ことができます。ある時点で、クエリは関連付けを返します。

その後、スキーマを調整して機能させることができる場合があります (SQLMetal のソースは利用できません :( )

于 2010-06-10T05:12:07.903 に答える