2

我在 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,列不允许空值

在我的 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 的标识插入中获取最后一个值。

所以我想问题归结为:我可以在 LINQ 中拥有一个不使用基础 SQL 中的标识列的自动生成的主键属性吗?我可以采取另一种方法来产生相同的结果吗?

注意:我想避免更改应用程序代码。理想情况下,当我将现有表从使用线性增量主键更改为随机生成的表时,这应该可以正常工作。

4

1 回答 1

1

在 DBML 设计器中,将该列的Auto Generated Value属性设置true为。这应该够了吧。

检查这个帖子,以及MSDN 论坛中的这个线程

于 2013-01-13T21:54:57.977 回答