我的问题非常简单:这里有两个一对多关系的课程。 我们来看一个样本: 摘自Julia Lerman的书"编程实体框架:代码优先"
push (@{ $hash2{$numbers} }, $items)
这里配置了FluentApi:
public class Destination
{
public int DestinationId { get; set; }
public string Name { get; set; }
public string Country { get; set; }
public string Description { get; set; }
public byte[] Photo { get; set; }
public ICollection<Lodging> Lodgings { get; set; }
public Destination()
{
Lodgings = new List<Lodging>();
}
}
public class Lodging
{
public int LodgingId { get; set; }
public string Name { get; set; }
public string Owner { get; set; }
public bool IsResort { get; set; }
public decimal MilesFromNearestAirport { get; set; }
public Destination Destination { get; set; }
public int DestinationId { get; set; }
}
我想那行
public class LodgingConfiguration : EntityTypeConfiguration<Lodging>
{
public LodgingConfiguration()
{
Property(p => p.Name).IsRequired().HasMaxLength(200);
HasRequired(p => p.Destination).WithMany(p => p.Lodgings);
}
}
public class DestinationConfiguration : EntityTypeConfiguration<Destination>
{
public DestinationConfiguration()
{
Property(p => p.Name).IsRequired().HasMaxLength(100);
Property(p => p.Description).HasMaxLength(500);
Property(p => p.Photo).HasColumnType("image");
HasMany(p=>p.Lodgings).WithRequired(l=>l.Destination);
}
}
和
HasRequired(p => p.Destination).WithMany(p => p.Lodgings);
在目的地和住宿之间的关系上提供相同的结果。
如果我只定义其中一条规则,它也可以正常工作。 在双方定义相同的规则是一个好习惯还是单边声明是好的?
答案 0 :(得分:1)
这两种配置都是罚款。如果你真的需要它,这是一个很好的做法。如果不保持关系简单,只显示有意义的实体中的导航属性。 (这与您的实体模型相关的问题比EF更多)
答案 1 :(得分:1)
如果您对这三种变体add-migration
执行了以下结果:
使用住宿和目的地配置类型中的映射
public override void Up()
{
CreateTable(
"dbo.Lodgings",
c => new
{
LodgingId = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 200),
Owner = c.String(),
IsResort = c.Boolean(nullable: false),
MilesFromNearestAirport = c.Decimal(nullable: false, precision: 18, scale: 2),
Destination_DestinationId = c.Int(nullable: false),
})
.PrimaryKey(t => t.LodgingId)
.ForeignKey("dbo.Destinations", t => t.Destination_DestinationId, cascadeDelete: true)
.Index(t => t.Destination_DestinationId);
CreateTable(
"dbo.Destinations",
c => new
{
DestinationId = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 100),
Country = c.String(),
Description = c.String(maxLength: 500),
Photo = c.Binary(storeType: "image"),
})
.PrimaryKey(t => t.DestinationId);
}
从住宿配置类型中删除映射
public override void Up()
{
CreateTable(
"dbo.Lodgings",
c => new
{
LodgingId = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 200),
Owner = c.String(),
IsResort = c.Boolean(nullable: false),
MilesFromNearestAirport = c.Decimal(nullable: false, precision: 18, scale: 2),
Destination_DestinationId = c.Int(nullable: false),
})
.PrimaryKey(t => t.LodgingId)
.ForeignKey("dbo.Destinations", t => t.Destination_DestinationId, cascadeDelete: true)
.Index(t => t.Destination_DestinationId);
CreateTable(
"dbo.Destinations",
c => new
{
DestinationId = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 100),
Country = c.String(),
Description = c.String(maxLength: 500),
Photo = c.Binary(storeType: "image"),
})
.PrimaryKey(t => t.DestinationId);
}
从目标配置类型中删除映射
public override void Up()
{
CreateTable(
"dbo.Lodgings",
c => new
{
LodgingId = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 200),
Owner = c.String(),
IsResort = c.Boolean(nullable: false),
MilesFromNearestAirport = c.Decimal(nullable: false, precision: 18, scale: 2),
Destination_DestinationId = c.Int(nullable: false),
})
.PrimaryKey(t => t.LodgingId)
.ForeignKey("dbo.Destinations", t => t.Destination_DestinationId, cascadeDelete: true)
.Index(t => t.Destination_DestinationId);
CreateTable(
"dbo.Destinations",
c => new
{
DestinationId = c.Int(nullable: false, identity: true),
Name = c.String(nullable: false, maxLength: 100),
Country = c.String(),
Description = c.String(maxLength: 500),
Photo = c.Binary(storeType: "image"),
})
.PrimaryKey(t => t.DestinationId);
}
如您所见,生成的代码(在本例中为Sql server)完全相同。它始终是一种风格问题,并且要保持一致。您可以在父配置类型或任何其他样式中显式设置子映射。
Here是关于这个主题的非常好的答案。
答案 2 :(得分:1)
只定义一次(例如)
modelBuilder.Entity<Student>()
.HasRequired<Course>(s => s.Course)
.WithMany(s => s.Students);
请记住,您需要维护代码。在两个单独的表示/位置中具有相同的信息是错误的处方。你认为团队中的每个人都会那么细致吗?