我希望你能帮助我。
我在db中有2个表:Bill和BillItem。这些表在db中配置为一对一关系,其中bill是主表,而BillItem是从属表
表Bill的结构:
Int BillId (PK)
Int BillTypeId Not Null
Varchar(5) Usr Not Null
DateTime Tm Not Null
表BillItem的结构:
Int BillItemId (PK)
Int ItemId Not Null
Varchar(5) Usr Not Null
DateTime Tm Not Null
我想使用Fluent API和Entity Framework 4.1 Code First方法将这两个表映射到一个POCO类
我还想配置表列名称以在POCO类中使用不同的属性名称(即Id而不是BillId,User而不是Usr)
这是一个遗留数据库,我无法修改其任何对象。
如何实现?
谢谢大家。
结果类应该是(如果可以的话):
public int Id {get;set;}
public int BillTypeId {get;set;}
public int ItemId {get;set;}
public string User {get;set;}
public string User1 {get;set;}
public DateTime Tm {get;set;}
public DateTime Tm1 {get;set;}
答案 0 :(得分:0)
对于重命名列,这很容易:
[Table("SomeHorribleTableName")]
public class MyNiceTableName
{
[Column("Usr")]
public string User { get; set; }
}
这里我也重命名了实体..不需要保留一个可怕的表名。关于映射2个表到1个实体..我不认为这是可能的。见这里:Mapping data from 2 tables to 1 entity - Entity Framework 4
流体风格:
public class Bill
{
public int ID { get; set; }
public int BillTypeID { get; set; }
public string UserName { get; set; }
public DateTime Time { get; set; }
}
public class BillItem
{
public int ID { get; set; }
public int ItemID { get; set; }
public string UserName { get; set; }
public DateTime Time { get; set; }
}
internal class BillMap : EntityTypeConfiguration<Bill>
{
public BillMap()
{
ToTable("Bills");
HasKey(x => x.ID);
Property(x => x.ID).HasColumnName("BillId");
Property(x => x.BillTypeID).IsRequired().HasColumnName("BillTypeId");
Property(p => p.UserName).IsRequired().HasColumnName("Usr");
Property(x => x.Time).IsRequired().HasColumnName("Tm");
}
}
internal class BillItemMap : EntityTypeConfiguration<BillItem>
{
public BillItemMap()
{
ToTable("BillItems");
HasKey(x => x.ID);
Property(x => x.ID).HasColumnName("BillItemId");
Property(x => x.ItemID).IsRequired().HasColumnName("ItemId");
Property(p => p.UserName).IsRequired().HasColumnName("Usr");
Property(x => x.Time).IsRequired().HasColumnName("Tm");
}
}
这可能是我能做的最好的事情。至于在两个表中处理Usr列,这些都是您应该在自己的控制器类/业务逻辑层中处理的事情。
还有一件事:对于上面的配置类,请在DbContext中调用它们,如下所示:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new BillMap());
modelBuilder.Configurations.Add(new BillItemMap());
}
答案 1 :(得分:0)
我认为您可以通过Entity Splitting功能实现这一目标,但您需要使用一些数据注释(无esacpe):
警告:我还没有尝试过这种方法,但可能会工作,如果您喜欢,请检查
第一个:使用HasColumnName
数据注释在单个域模型类中注释属于BillItem表的属性。
第二:使用此代码示例
public class YourSingleModelClassNameConfiguration : EntityTypeConfiguration<YourSingleModelClassName> {
public YourSingleModelClassNameConfiguration() {
ToTable("Bill"); Property(param => param.Id).IsRequired().HasColumnName("BillId");
// NOW REPEAT THAT FOR ALL BILL PROPERTIES WITH YOUR REQUIRED ATTRIBUTES (ISREQUIRED OR NOT, LENGTH ...)
// NOW THE PROPERTIES YOU NEED TO MAP TO THE BILL ITEMS TABLE GOES INTO THE MAP FUNCTION
Map(
param =>
{ param.Properties(d => new {d.ItemId, d.User1}); m.ToTable("BillItem");
}
);
// DON'T FORGET TO MENTION THE REST OF THE PROPERTIES BELONGING TO THE BillItem TABLE INSIDE THE PROPERTIES METHOD IN THE LAST LINE.
}
}
答案 2 :(得分:0)
对于这个问题,你可以很容易地做到这一点,你有两个选择。第一种是使用实体框架(mapping multiple tables to a single entity class in entity framework)映射类。
第二个选项是手动执行: 2个表必须遵循的限制是1必须是强表,第二个必须是弱表(通过这样做,你应该只从强表到弱表1),否则,这不会起作用结果将是一个对象集合,然后您需要决定第一个对象是否是您需要的对象而不是其他对象。
如果你想使用稍微快一点的方法,我建议使用你自己的逻辑来映射POCO对象。创建将与数据库表映射的2个clases以及从服务对象构建对象。
这种方法很好,因为生成的LINQ查询不会使用INNER JOINS,这会使它更快。但加入应该在你身边。
实施例
int i=0;
// this 2 refer to the 2 different mapped tables in your context database
var pbdata = _pbdata.GetSingle(p=>p.StrongTableID == StrongTableID);
var pb = _pb.GetSingle(p=>p.WeakTableID == pbdata.WeakTableID);
// you can see that i am looking for the StrongTableID in order to select the entity value
// this is optional but usefull! you can do the
// "copy" inside a function where in future if the
// object changes, you can update easily
ObjectComposite.Map(body, ref pb, ref pbdata);
// the following proccess needs to be done like this...
// first save the value in the weak object so
// the WeakTableID is recorded
// UPDATE: maybe these 2 should go into a transact for more security... but... ok...
Save(pb);
i += this.unitOfWork.Save();
pbdata.ProfessionalBodyID = pb.ProfessionalBodyID;
// once the values for the second objects are set, save it all again.
Save(pbdata);
i += this.unitOfWork.Save();
return i > 0 ? true : false;
这种方法更快,但您需要控制自己的一切。好的是,你可以在这里映射任意数量的表
希望它有所帮助!