Entity Framework v5 看起来很酷,我尝试使用现有的MSSQL (Azure) 数据库从 Linq 切换到 SQL。但是关于 EF 的教程太复杂了,无法遵循。
数据库模式非常简单,如下所示(由存在数据库生成)。
Sheets和SheetDetails表以一对多的关系连接。
CREATE TABLE [dbo].[Sheets] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Grade] FLOAT (53) CONSTRAINT [DF_Sheets_Grade] DEFAULT ((0)) NOT NULL,
[Title] NVARCHAR (255) CONSTRAINT [DF_Sheets_Title] DEFAULT ('') NOT NULL,
[Description] NVARCHAR (255) NULL,
[Difficulty] SMALLINT CONSTRAINT [DF_Sheets_Difficulty] DEFAULT ((0)) NOT NULL,
[Writer] NVARCHAR (255) CONSTRAINT [DF_Sheets_Writer] DEFAULT ('') NOT NULL,
[Tag] NVARCHAR (255) NULL,
[Duration] FLOAT (53) CONSTRAINT [DF_Sheets_Duration] DEFAULT ((0)) NOT NULL,
[Timestamp] DATETIME CONSTRAINT [DF_Sheets_Timestamp] DEFAULT ((0)) NOT NULL,
[RowVersion] ROWVERSION NOT NULL,
CONSTRAINT [PK_Sheets] PRIMARY KEY CLUSTERED ([Id] ASC)
);
CREATE TABLE [dbo].[SheetDetails] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Score] FLOAT (53) CONSTRAINT [DF_SheetDetails_Score] DEFAULT ((0)) NOT NULL,
[Number] SMALLINT CONSTRAINT [DF_SheetDetails_Number] DEFAULT ((0)) NOT NULL,
[SubNumer] SMALLINT NULL,
[IsRandom] BIT CONSTRAINT [DF_SheetDetails_IsRandom] DEFAULT ((0)) NOT NULL,
[AnswerType] SMALLINT CONSTRAINT [DF_SheetDetails_AnswerType] DEFAULT ((0)) NOT NULL,
[RowVersion] ROWVERSION NOT NULL,
[SheetDetail_Sheet] INT CONSTRAINT [DF_SheetDetails_SheetDetail_Sheet] DEFAULT ((0)) NOT NULL,
[SheetDetail_Question] INT CONSTRAINT [DF_SheetDetails_SheetDetail_Question] DEFAULT ((0)) NOT NULL,
CONSTRAINT [SheetDetail_Sheet] FOREIGN KEY ([SheetDetail_Sheet]) REFERENCES [dbo].[Sheets] ([Id]) ON DELETE CASCADE
);
请注意,FK 名称是 SheetDetails 表中的 SheetDetail_Sheet。
结果图如下。
接下来,也许我需要编写EntityTypeConfiguration。我将其作为问题 1 进行了尝试。
问题 1. 我编写模型创建配置如下,但没有运气。这是错的吗?很难知道如何用这个简单的数据库模型编写正确的配置。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new SheetsConfiguration());
base.OnModelCreating(modelBuilder);
}
public class SheetsConfiguration : EntityTypeConfiguration<Sheets>
{
public SheetsConfiguration()
: base()
{
HasKey(p => p.Id);
Property(p => p.Id).HasColumnName("Id").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired();
Property(p => p.RowVersion).IsConcurrencyToken().IsRowVersion();
HasOptional(p => p.SheetDetails).WithMany().Map(x => x.MapKey("SheetDetail_Sheet"));
ToTable("Sheets");
}
}
我使用执行简单查询
var result = _db.Sheets.Where(sheet => sheet.Id == id).ToList();
然后,执行查询时出现错误“列名 SheetDetail_Sheet 无效”,如下所示。
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Grade] AS [Grade],
[Extent1].[Title] AS [Title],
[Extent1].[Description] AS [Description],
[Extent1].[Difficulty] AS [Difficulty],
[Extent1].[Writer] AS [Writer],
[Extent1].[Tag] AS [Tag],
[Extent1].[Duration] AS [Duration],
[Extent1].[Timestamp] AS [Timestamp],
[Extent1].[RowVersion] AS [RowVersion],
[Extent1].[SheetDetail_Sheet] AS [SheetDetail_Sheet]
FROM [dbo].[Sheets] AS [Extent1]
WHERE [Extent1].[Id] = @p__linq__0
我可以理解,因为SheetDetail_Sheet 只是一个 FK,并不存在于 edmx 属性和数据库列中。我该如何解决?
我不想编辑自动生成的模型文件,因为它可以被覆盖。也许它似乎是通过 EntityTypeConfiguration 实现的。
问题2. 常用的主从数据库模型有什么有用的轻量级参考吗?
我在从现有数据库开始时遇到了麻烦。stackoverflow, asp.net, blogs, etc...很多教程,但很难找到像我这样的例子。
谢谢你。