我有以下实体:
[KnownType(typeof(Script))]
public class Application : IEntity
{
public long ID { get; set; }
public string Name { get; set; }
public long? StartScriptID { get; set; }
// Other properties...
// Navigation properties:
public virtual Script StartScript { get; set; } // new
public virtual List<Script> Scripts { get; set; }
}
[KnownType(typeof(Application))]
public class Script : IEntity
{
public long ID { get; set; }
public string Name { get; set; }
// Other properties...
// Navigation properties:
public virtual Application Application { get; set; }
}
我在DbContext
因此模型存在必须绑定到应用程序的脚本。应用程序可以定义startScript。所有这些我已经有了工作。
现在我需要一个导航属性:Application.StartScript
。
问题是如何在Application
上添加导航属性,而必须在Script
上添加等效的导航属性。
提前致谢!
编辑:当我运行Add-Migration时,会生成以下迁移代码:
public override void Up()
{
DropForeignKey("dbo.Scripts", "ApplicationID", "dbo.Applications");
AddColumn("dbo.Scripts", "Application_ID", c => c.Long());
CreateIndex("dbo.Applications", "StartScriptID");
CreateIndex("dbo.Scripts", "Application_ID");
AddForeignKey("dbo.Applications", "StartScriptID", "dbo.Scripts", "ID");
AddForeignKey("dbo.Scripts", "Application_ID", "dbo.Applications", "ID");
}
这会在Scripts上创建一个我不需要的新列,因为我已经有了StartScriptID列。
编辑:@ haim770回答后更新
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Application>().HasOptional(x => x.StartScript).WithOptionalDependent(x => x.Application);
}
public override void Up()
{
DropForeignKey("dbo.Scripts", "ApplicationID", "dbo.Applications");
DropIndex("dbo.Scripts", new[] { "ApplicationID" });
RenameColumn(table: "dbo.Applications", name: "ApplicationID", newName: "StartScript_ID");
AddColumn("dbo.Scripts", "Application_ID", c => c.Long());
CreateIndex("dbo.Applications", "StartScript_ID");
CreateIndex("dbo.Scripts", "Application_ID");
AddForeignKey("dbo.Scripts", "Application_ID", "dbo.Applications", "ID");
AddForeignKey("dbo.Applications", "StartScript_ID", "dbo.Scripts", "ID");
}
它不明白它应该使用已经存在的StartScriptID。有没有办法将它指向正确的方向?
编辑:通缉数据库结构:
应用:
脚本:
编辑:
public class Application
{
[InverseProperty("StartScript")]
public long? StartScriptID { get; set; }
[ForeignKey("StartScriptID")]
public virtual Script StartScript { get; set; }
}
我当时认为数据库中没有需要进行任何更改,因此我尝试使用-IgnoreChanges添加迁移。但是在查询实体时我得到EntityCommandExecutionException
:“无效的列名'Application_ID'”。因此,实体框架需要一些配置来告知使用StartScriptID
属性。
答案 0 :(得分:0)
您可以使用ForeignKeyAttribute和InversePropertyAttribute修改映射。 如果这不符合您的要求,您可以在应用之前自行编辑迁移。
如果要自定义列名,请尝试使用ColumnAttribute:
public class Application
{
[Column("DatabaseColumnName")]
public long? StartScriptID { get; set; }
[ForeignKey("StartScriptID")]
public virtual Script StartScript { get; set; }
}
可以在此处找到更长的解释:http://msdn.microsoft.com/de-de/data/gg193958.aspx
答案 1 :(得分:0)
尝试使用EntityTypeConfiguration这样可以更轻松地处理此类问题。然后:
public class Application
{
public long ID { get; set; }
public string Name { get; set; }
public long? StartScriptID { get; set; }
// Other properties...
// Navigation properties:
public virtual Script StartScript { get; set; } // new
public virtual ICollection<Script> Scripts { get; set; }
}
public class Script
{
public long ID { get; set; }
public string Name { get; set; }
public int ApplicationId { get; set; }
// Other properties...
// Navigation properties:
public virtual Application Application { get; set; }
}
public class ApplicationMap : EntityTypeConfiguration<Application>
{
public ApplicationMap()
{
this.HasKey(t => t.ID);
this.ToTable("TB_APLICATION", "aplication");
this.Property(t => t.ID).HasColumnName("id");
this.Property(t => t.Name).HasColumnName("name");
this.Property(t => t.StartScriptID).HasColumnName("startscript_id");
this.HasOptional(t => t.StartScript)
.WithMany()
.HasForeignKey(t => t.StartScriptID);
}
}
public class ScriptMap : EntityTypeConfiguration<Script>
{
public ScriptMap()
{
this.HasKey(t => t.ID);
this.ToTable("TB_APLICATION", "aplication");
this.Property(t => t.ID).HasColumnName("id");
this.Property(t => t.Name).HasColumnName("name");
this.HasRequired(t => t.Application)
.WithMany(w => w.Scripts)
.HasForeignKey(t => t.ApplicationId);
}
}
别忘了告诉EF关于映射:(在里面调用 OnModelCreating )
public static class MappingConfig
{
public static void ConfigureMap(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ApplicationMap());
modelBuilder.Configurations.Add(new ScriptMap());
}
}