2

我有一个名为 Room 的数据库表。

此表在某些列上有一些默认值:

ALTER TABLE [dbo].[Room] ADD  CONSTRAINT [DF_Room_Created]  DEFAULT (getdate()) FOR [Created]
GO

ALTER TABLE [dbo].[Room] ADD  CONSTRAINT [DF_Room_Updated]  DEFAULT (getdate()) FOR [Updated]
GO

ALTER TABLE [dbo].[Room] ADD  CONSTRAINT [DF_Room_RecordStatus]  DEFAULT (0) FOR [RecordStatus]

该表还具有以下触发器:

ALTER TRIGGER [dbo].[RoomInsert] ON [dbo].[Room]
FOR INSERT 
AS
DECLARE @PKey int, @TrackingId int
SELECT @PKey = PKey, @TrackingId = TrackingId FROM INSERTED
IF @TrackingId = 0
UPDATE Room
SET TrackingId = @PKey
WHERE PKey = @PKey

我们目前正在开发一个使用 Entity Framework 4 的 MVC 3 Web 应用程序。当我运行以下代码时,没有应用任何默认值,也没有触发触发器:

// Create the new room record
                Room newRoom = new Room();
                newRoom.SiteKey = parentFloor.SiteKey;
                newRoom.SiteSurveyKey = parentFloor.SiteSurveyKey;
                newRoom.BuildingKey = parentFloor.BuildingKey;
                newRoom.FloorKey = parentFloor.PKey;
                newRoom.Name = eventModel.RoomName;
                newRoom.Description = eventModel.RoomName;
                newRoom.CreatedBy = eventModel.UserKey;

                _entities.Rooms.AddObject(newRoom);
                _entities.SaveChanges();

我在数据库上运行了一个配置文件,插入产生以下内容:

exec sp_executesql N'insert [dbo].[Room]([TrackingID], [OriginalPKey], [BuildingKey], [SiteSurveyKey], [SiteKey], [Name], [Description], [RiskColour], [CreatedBy], [Created], [Updated], [RecordStatus], [FloorKey], [DisplayOrder])
values (null, null, @0, @1, @2, @3, @4, null, @5, null, null, null, @6, null)
select [PKey]
from [dbo].[Room]
where @@ROWCOUNT > 0 and [PKey] = scope_identity()',N'@0 int,@1 int,@2 int,@3 varchar(255),@4 varchar(255),@5 int,@6 int',@0=29970,@1=20177,@2=39373,@3='Another Room ',@4='Another Room ',@5=139,@6=25454

我猜测没有应用默认值,因为 NULL 是专门传递的,并且由于 sp_executesql 而没有触发触发器。有没有办法解决这个问题?

4

3 回答 3

1

When you use EF you basically just have to accept that the application is the master, not the database.

You should set default values in your Room constructor, not through database default constraints (admittedly with created / updated date you might want to do this at the db for timezone reasons etc...)

Entity Framework - Default value for property using Data Annotations

于 2013-02-25T11:25:55.913 回答
1

As @JustAnother... says, the contraints will be of little use, as you'll always have a value supplied, however your trigger should still work ok.

In the SQL trace you'll see that the value of TrackingID is null. In your trigger you're testing for TrackingID=0, which is false when TrackingID = null.

Try updating the trigger to test for null as well.

于 2013-02-25T11:26:59.293 回答
1

实体框架不关心您的默认约束。只要您的列在 EF 模型中未标记为 Identity 或 Computed,它将始终提交一个值。当您将列更改为“计算”时,您无法再使用实体对象更新列,它将始终采用数据库值(因此您的默认约束值)。

于 2013-02-25T11:21:18.173 回答