主キーとして使用されるランダムな整数を生成するために、SQL でユーザー定義関数を作成しました。
CREATE VIEW [dbo].[GetNewID]
AS
SELECT ABS(CAST(CAST(NEWID() AS VARBINARY) AS INT)) AS new_id;
CREATE FUNCTION [dbo].[RandomID] ()
RETURNS INT
AS
BEGIN
DECLARE @new_id AS INT
SET @new_id = (SELECT new_id FROM GetNewID)
IF (SELECT COUNT(*) FROM Foo WHERE FooID = @new_id) != 0
SELECT @new_id = [dbo].[RandomID]()
RETURN @new_id
END;
次の表を使用します。
CREATE TABLE [dbo].[Foo] (
[FooID] [int] PRIMARY KEY DEFAULT([dbo].[RandomID]()),
[val] [varchar](32)
);
SQL を使用してレコードを挿入すると、期待どおりに機能します。
ただし、LINQ で新しいレコードを作成しようとすると、次のエラーが発生します。
値 Null を列 ID に挿入できません。列は null を許可しません
私の LINQ to SQL モデルFooID
には、次の列属性があります。
[ColumnAttribute(Storage="_FooID", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL", IsPrimaryKey=true, IsDbGenerated=true)]
LINQ によって生成された SQL を確認すると、問題は明らかです。
INSERT INTO [dbo].[Foo]([val])
VALUES (@p0)
SELECT CONVERT(Int,SCOPE_IDENTITY()) AS [value]
-- @p0: Input VarChar (Size = 8000; Prec = 0; Scale = 0) [Testing]
LINQ は、null を返す ID 挿入から最後の値を取得しようとしています。
したがって、問題は次のようになると思います。基礎となる SQL で ID 列を使用しない自動生成された主キー プロパティを LINQ で使用できますか? 同じ結果が得られる別のアプローチはありますか?
注: アプリケーション コードの変更は避けたいと思います。理想的には、既存のテーブルを線形増分主キーの使用からランダムに生成されたものに変更するときに、これはうまく機能するはずです。