Entity framework 4 TPH继承映射使用nchar(N'value')而不是char('value')作为鉴别器列值
我正在使用一个现有的数据库,并首先使用EF4.3代码。我有一个如下所示的实体层次结构,其中Note是基类:Entity framework 4 TPH继承映射使用nchar(N'value')而不是char('value')作为鉴别器列值,entity-framework-4,ef-code-first,Entity Framework 4,Ef Code First,我正在使用一个现有的数据库,并首先使用EF4.3代码。我有一个如下所示的实体层次结构,其中Note是基类: Note - CompanyNote - OrderNote - etc 我正在使用具有以下映射的鉴别器列: Map<CompanyNote>(t => t.Requires("type").HasValue("company")); Map<OrderNote>(t => t.Requires("type").HasValue("orde
Note
- CompanyNote
- OrderNote
- etc
我正在使用具有以下映射的鉴别器列:
Map<CompanyNote>(t => t.Requires("type").HasValue("company"));
Map<OrderNote>(t => t.Requires("type").HasValue("order"));
这是一个问题,因为这个表有数千行,它阻止SQL使用索引。我需要查询以这样看:
SELECT /* columns */
FROM [dbo].[notes] AS [Extent1]
WHERE [Extent1].[type] = 'company'
以下是我迄今为止所尝试的:
添加类型属性并将其映射为
Propertyt=>t.Type.IsFixedLength.HasMaxLength18.IsUnicodalse;
使用将列配置添加到继承映射
Mapt=>t.requireType.HasValuecompany.IsFixedLength.HasMaxLength18.IsUnicodalse;
这两个变化都没有改变。不幸的是,我无法将数据库列类型更改为nchar
我如何告诉EntityFramework鉴别器列的类型是char
更新:这里有一个完整的例子
我无法在SQL查询中重现Unicode字符串的使用。使用EF 4.3.1测试应用程序控制台应用程序:
using System;
using System.Data.Entity;
using System.Linq;
namespace EF43TPH
{
public abstract class Note
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CompanyNote : Note
{
public string ExtendedName { get; set; }
}
public class OrderNote : Note
{
public string AnotherExtendedName { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Note> Notes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<CompanyNote>()
.Map<CompanyNote>(t => t.Requires("type").HasValue("company"));
modelBuilder.Entity<OrderNote>()
.Map<OrderNote>(t => t.Requires("type").HasValue("order"));
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
using (var ctx = new MyContext())
{
try
{
var query = ctx.Notes.OfType<CompanyNote>();
var queryString = query.ToString();
}
catch (Exception e)
{
throw;
}
}
}
}
}
这个测试和您的代码有什么不同?我仍然不确定为什么我看到的结果与@Slauma不同,但我终于找到了适合我的东西。我在继承映射中将列类型显式设置为char
Map<TphTestCompanyNote>(t => t.Requires("type")
.HasValue("company")
.HasColumnType("char"));
Map<TphTestOrderNote>(t => t.Requires("type")
.HasValue("order")
.HasColumnType("char"));
一个区别是我使用ctx.Set而不是ctx.Set.OfType进行查询。我将整理一个最小但完整的示例,并更新我的问题。@jrummell:如果我将LINQ查询更改为您的查询,我将得到相同的SQL。我复制并粘贴了您的模型。我得到了完全相同的查询,但其中[Extent1].[type]='company'。您使用的EF的具体版本是什么?什么数据库和数据库版本?顺便说一句:如果您没有将DB初始值设定项设置为null,您将由于EF 4.3.1中的错误而得到一个异常:这很奇怪。我有EF4.3.1.0和SQLServer2005。我的模型中没有上下文的连接字符串,而且它从来没有实际命中数据库,因此,我不确定这是否重要。如果您没有提供连接字符串和上下文构造函数参数,EF将使用System.Data.SqlClient提供程序(称为SQL Server的.NET Framework数据提供程序)并尝试连接到。\SQLEXPRESS DB实例。该提供程序适用于SQLServer2005及更高版本,据我所知,应该生成相同的SQL。如果您使用了另一个提供程序,那么即使不触及数据库,这也很重要,因为另一个提供程序可以生成其他SQL。您正在使用.NET4.0吗?或4.5?.NET 4.0。我没有意识到它正在连接到本地计算机上的。\SQLEXPRESS,我通过停止服务并获取ProviderIncompatibleException进行了确认。那个版本的SQL Server是2008版的。@Slauma,我不知道为什么我们在相同的代码和相同版本的EF中看到不同的结果,但我发现了其他一些有效的方法。看我的答案。我也测试过了,但因为它对我的工作方式与你的原始代码相同,我认为这无关紧要,也没有什么区别。真奇怪,为什么这适用于您的映射,而不是原始映射。我不知道原因是什么。
using System;
using System.Data.Entity;
using System.Linq;
namespace EF43TPH
{
public abstract class Note
{
public int Id { get; set; }
public string Name { get; set; }
}
public class CompanyNote : Note
{
public string ExtendedName { get; set; }
}
public class OrderNote : Note
{
public string AnotherExtendedName { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Note> Notes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<CompanyNote>()
.Map<CompanyNote>(t => t.Requires("type").HasValue("company"));
modelBuilder.Entity<OrderNote>()
.Map<OrderNote>(t => t.Requires("type").HasValue("order"));
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
using (var ctx = new MyContext())
{
try
{
var query = ctx.Notes.OfType<CompanyNote>();
var queryString = query.ToString();
}
catch (Exception e)
{
throw;
}
}
}
}
}
Map<TphTestCompanyNote>(t => t.Requires("type")
.HasValue("company")
.HasColumnType("char"));
Map<TphTestOrderNote>(t => t.Requires("type")
.HasValue("order")
.HasColumnType("char"));
SELECT
'0X0X' AS [C1],
[Extent1].[id] AS [id],
[Extent1].[text] AS [text]
FROM [dbo].[notes] AS [Extent1]
WHERE [Extent1].[type] = 'company'