我目前使用Table Per Type(TPT)实现了Entity Framework 4.0模型,但是存在一些性能问题(许多LOJ/CASE语句),以及两个特定域区域之间的问题映射(多个到 - 许多).
我决定尝试TPH.
我有一个名为" Location " 的实体,它是抽象的,是所有其他实体的基础.
然后我有" 国家 "," 城市 "," 州 "," 街道 "等,这些都来自位置.
" LocationType "是判别者.
该部分工作正常,但我在尝试为派生类型定义导航属性时遇到问题.
例如," 州 "有一个" 国家 ",所以我应该能够这样做:
var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;
Run Code Online (Sandbox Code Playgroud)
但这需要在"州"派生实体上称为"国家"的导航属性.我该怎么做呢?当我从数据库生成模型时,我有一个表,所有FK指向同一个表中的记录:
(注意:我在DB中手动创建了这些FK).
但是FK被定位为" 位置 "实体上的导航,那么如何将这些导航属性移动到派生实体?我不能复制+粘贴导航,我不能"创建新的导航属性",因为它不会让我定义开始/结束角色.
我们如何做到这一点?
如果我们可以先建立模型,或者我们必须从数据库开始,修复模型然后重新生成数据库,那么TPH也不清楚.我还没有在互联网上找到一个关于如何使用TPH定义儿童导航的好例子.
注意:我不想先执行代码.我目前的解决方案是TPT与EDMX,以及纯POCO,我希望不影响域模型/存储库(如果可能),只需更新EF模型/数据库.
编辑
仍然没有解决方案 - 但是我试图做模型优先,并做Add - > New Association,这实际上允许我向派生实体添加导航.但是当我尝试"从模型生成数据库"时,它仍然尝试为"Location_Street","Location_Country"等创建表.这几乎就像TPH不能先完成模型.
编辑
这是我目前的型号:
我目前得到的验证错误:
错误1错误3002:从第359行开始映射片段时出现问题:潜在的运行时违反表位置的键(Locations.LocationId):列(Locations.LocationId)在概念方面映射到EntitySet NeighbourhoodZipCode的属性(NeighbourhoodZipCode.Neighbourhood.LocationId)但它们并不构成EntitySet的关键属性(NeighbourhoodZipCode.Neighbourhood.LocationId,NeighbourhoodZipCode.ZipCode.LocationId).
只是想我会继续编辑这个问题,编辑关于我目前所处的位置.我开始怀疑具有自引用FK的TPH是否可行.
编辑
所以我想出了上面的错误,那是因为我错过了Neighborhood-ZipCode的连接表多对多.
添加连接表(并将导航映射到该表)解决了上述错误.
但现在我得到这个错误:
错误3032:从第373行,第382行开始映射片段时出现问题:条件成员的Locations.StateLocationId'具有重复的条件值.
如果我看一下CSDL,这里是"CountyState"的关联映射(一个州有很多县,一个县有一个州):
<AssociationSetMapping Name="CountyState" TypeName="Locations.CountyState" StoreEntitySet="Locations">
<EndProperty Name="State"> …
Run Code Online (Sandbox Code Playgroud) c# entity-framework sql-server-2008 entity-framework-4 table-per-hierarchy
我有一个Garage
包含Cars
和Motorcycles
.汽车和摩托车是Vehicles
.他们来了:
public class Garage
{
public int Id { get; set; }
public virtual List<Car> Cars { get; set; }
public virtual List<Motorcycle> Motorcycles { get; set; }
public Garage()
{
Cars = new List<Car>();
Motorcycles = new List<Motorcycle>();
}
}
public abstract class Vehicle
{
public int Id { get; set; }
public string Make { get; set; }
public string Model { get; set; }
}
public class Car : …
Run Code Online (Sandbox Code Playgroud) 我正在使用遗留系统,为一定数量的项目实现TPH.所以目前的结构看起来像这样
Abstract Class 1 Abstract Class 2 Abstract Class 3
| | |
--------- --------- ---------
| | | | | | | | |
T1 T2 T3 T4 T5 T6 T7 T8 T9
Run Code Online (Sandbox Code Playgroud)
因此Type(T*)是跨所有表的鉴别器,但由于某些类型共享公共列,因此存在大量不同的表.问题是所有这些项目实际上都有一个共同点,但没有办法将所有这些项目收集到一个集合中.实际上,层次结构实际上看起来应该更像这样.
--------------- Base Abstract 1 ----------
| | |
Abstract Class 1 Abstract Class 2 Abstract Class 3
| | |
--------- --------- ---------
| | | | | | | | |
T1 T2 T3 T4 T5 T6 T7 T8 T9
Run Code Online (Sandbox Code Playgroud)
基本上我们所拥有的是TPT,其中每种类型的每个表都是TPH.对于一个真实世界的例子,这是我们需要的.
--------------- Vehicle --------------- …
Run Code Online (Sandbox Code Playgroud) 我试图理解EF4中的继承映射.
我的数据库有两个表,结构如下:
PersonCategory表:
人员表
PersonCategory表有四个条目,每个条目代表一个类别 - Student,CourseInstructor,Staff和Advisor.
从在线阅读文章,我认为Table Per Hierarchy将是适用于此场景的模型.所以在EF4中,我创建了四个实体(Student,CourseInstructor,Staff和Advisor),每个实体都继承自Person表.然后我将它们中的每一个映射到Person表并向每个表添加一个条件(例如,StudentID = 1表示Student实体,CategoryID = 2表示Staff实体)以区别于其他表.我还从Person表中删除了CategoryID属性并使其成为抽象类.但是我收到以下错误,因为我从Person表中删除了CategoryId属性.
错误3015:从第101,108,114,120,126,133行开始映射片段时出现问题:从表Person(CategoryID)到表PersonCategory(CategoryID)的外键约束'FK_Person_PersonCategory'::映射不足:必须映射外键一些参与概念方面的外键关联的AssociationSet或EntitySets.
Table Per Hierarchy是适用于此场景的模型吗?如果没有,那么我应该如何在EF4中处理这种情况?
.net inheritance hierarchy entity-framework-4 table-per-hierarchy
从EF6开始,在使用Table Per Hierarchy继承配置实体映射时,可以执行类似的操作:
public class MyContext : DbContext
{
public DbSet<Device> Devices { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ABatteryPoweredDevice>().Property(c => c.BatteryLevel).HasColumnName("BatteryLevel");
modelBuilder.Entity<ADifferentBatteryPoweredDevice>().Property(c => c.BatteryLevel).HasColumnName("BatteryLevel");
}
}
Run Code Online (Sandbox Code Playgroud)
BatteryLevel
不是Device
基类的一部分 - 它是为实现接口契约而实现的派生类的属性.
是否可以将此作为默认行为,而不是必须为每个派生类添加新映射?
我正在使用Table Per Hierarchy数据库继承,其中所有派生类型的列都在一个表中.每个派生表都使用字符串Discriminator字段标识,该字段包含派生类的名称:
---------------------
| tanimal |
---------------------
| animalid |
| discriminator |
| furcolour |
| feathercolour |
---------------------
public abstract class Animal
{
public int AnimalId { get; set; }
public string Discriminator { get { return GetType().Name; } }
}
public class Bird : Animal
{
public string FeatherColour { get; set; }
}
public class Dog : Animal
{
public string FurColour { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
正如所料,当我通过Dapper的查询方法检索这个时,我会收到Instances of abstract classes cannot be created …
我有4个类A,B,B1,B2,其继承映射如下所述:
A(映射到表A)是最顶层的父类,它的继承映射策略是tablePerHierarchy=false
(意味着它的每个子类映射到一个单表).
B类从A延伸,B1,B2从B延伸.但是B1和B2与B共用同一个表,因此在B类中,我声明tablePerHierarchy=true
并使用鉴别器来分离B1和B2.
详细代码如下:
class A {
static mapping = {
tablePerHierarchy false
table 'A'
}
}
class B extends A {
static mapping = {
tablePerHierarchy true
table 'B'
discriminator column : 'TYPE'
}
String bProp1
String bProp2
}
class B1 extends B {
static mapping = {
discriminator column : 'TYPE', value : 'B1'
}
String b1Props1
String b1Props2
}
class B2 extends B {
static mapping = {
discriminator column : 'TYPE', value …
Run Code Online (Sandbox Code Playgroud) 我有一个使用每个层次结构的表的实体框架模型.基类是抽象的,有两个派生类.
我想在这两个派生类和另一个类之间创建关联.这些是多对多的关系,所以通过加入表.
添加第一个关联是可以的,但是当我添加第二个时,我得到了这个错误:
错误3034:从第1074行,第1082行开始映射片段时出现问题:具有可能不同键的两个实体映射到同一行.确保这两个映射片段将AssociationSet的两端映射到相应的列.
下面是模型相关部分的图像(LabelImages和PresetImages关联是给出麻烦的):
我正在使用EF 4.2代码优先模型开发项目.此模型包含产品的TPH继承结构.我需要在鉴别器上对这个继承模型的多态结果进行分组,并遇到一些问题.
实体框架不会公开鉴别器以完成此分组.我的第一个问题是我可以直接访问这个鉴别器吗?我的阅读和经验告诉我没有,所以我提出了这种解决方案.它表现不佳,我不满意如何维护它.
我的类看起来像这样(简化):
Public MustInherit Class Product
<key()>
Public Property ProductID as integer
<StringLength(50, ErrorMessage:="Max 50 characters")>
<Required(ErrorMessage:="Product name is required")>
Public Property Name as String
<TimeStamp()>
Public Property Time_Stamp as DateTime = DateTime.Now()
End Class
Public Class Desktop
Inherits Product
<StringLength(50, ErrorMessage:="Max 50 characters")>
<Required(ErrorMessage:="Processor is required")>
Public Property Processor as String
End Class
Public Class Monitor
Inherits Product
<Required(ErrorMessage:="Monitor size is required")>
Public Property Size_Inches as Integer
End Class
Run Code Online (Sandbox Code Playgroud)
我构建了一个扩展方法,它接受一个产品并将其基类型名称作为字符串返回.
<Extension()>
Public Function ProductType(ByVal inProduct as Product) …
Run Code Online (Sandbox Code Playgroud) vb.net group-by table-per-hierarchy ef-code-first discriminator
我有一个使用 Entity Framework Code First 创建的实体框架模型,该模型使用每个层次结构表继承,其中结构看起来有点像这样:
public abstract class BaseState
{
public int Id { get; set; }
public string StateName { get; set; }
// etcetera
}
public class CreatedState : BaseState
{
public User Owner { get; set; }
}
public class UpdatedState : BaseState
{
public User Owner { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在创建的内容在我拥有并存储的BaseStates
表中。但考虑到没有一个类会同时是 a和 an ,似乎对两者都使用一个单一的类是合乎逻辑的。这也将使跟踪数据库变得更容易。Owner_Id
Owner_Id1
CreatedState
UpdatedState
Owner_Id
我的基本问题是:Code First EF4 可以实现这一点吗?
我尝试映射列:
public class CreatedState : BaseState
{
[Column("OwnerId")]
public …
Run Code Online (Sandbox Code Playgroud) c# ×5
inheritance ×3
.net ×2
dapper ×1
grails ×1
group-by ×1
hierarchy ×1
one-to-many ×1
vb.net ×1