Entity Framework 使用数据库或代码优先模型中不存在的列生成 sql
Entity Framework generate sql with column that does not exist in database or code first model
我有这样一种情况,entity framework 正在向合同模型添加一个 contract_id 列,而该列在 C# 模型中不作为 属性 存在,而且它不存在在数据库中。我已经梳理了数据库和解决方案,以供参考'contract_id',我正在为这个而绞尽脑汁。
[Export(typeof(IModel))]
[Grid.GridNavigator(cloneToTop = true, add = true, del = true, refresh = true, refreshstate = Grid.RefreshState.current, addfunc = "$.modules.grids.contract.add")]
[Grid.Events(serializeGridData = "$.modules.grids.common.serialize")]
public class Contract
: Model
, ILogicalDelete
{
#region properties
[Key]
[Grid.Column("ContractID", TypeName = "int", Label = "Contract ID", Width = 75, VisibleTo = new Type[] { typeof(Contract) })]
[Grid.Search(SearchOperators.equal)]
[Grid.Controls.Hidden]
public override int ID { get { return base.ID; } set { base.ID = value; } }
[Grid.Column("CorrelationID", Hidden = true)]
[Grid.Controls.Hidden]
public Guid? CorrelationID { get; set; }
//[Grid.Column("StatusID", ModelNavigation = "Status", HiddenFromNavigation = true)]
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
//public int StatusID { get; set; }
[MaxLength(100)]
[Grid.Column("ContractDesc", TypeName = "varchar", Label = "Description")]
[Grid.Search(SearchOperators.begins_with | SearchOperators.contains | SearchOperators.ends_with)]
[Grid.Controls.CustomEditable(Grid.ControlType.autocomplete, Url = "/api/contractservice/list?name=contract&column=ContractDesc&_type={0}", KeyField = "ID", TextField = "ContractDesc", ForReferenceUse = true)]
public string ContractDesc { get; set; }
[MaxLength(100)]
[Grid.Column("ContractType", TypeName = "varchar", Label = "Type", VisibleTo = new Type[] { typeof(Contract) }, HiddenFromNavigation = true)]
[Grid.Search(Grid.SearchType.select, url = "/api/contractservice/list?name=ContractType", build = "$.services.grid.ctrls.select.build")]
//[Grid.Controls.Select(Url = "/api/contractservice/list?name=ContractType", BuildSelect = "$.services.grid.ctrls.select.build")]
public string ContractType { get; set; }
[Grid.Column("Audited", TypeName = "bit", FormatterType = Grid.FormatterType.checkbox, Alignment = Grid.Position.center, Width = 50, HiddenFromNavigation = true)]
[JsonConverter(typeof(Grid.Serialization.BooleanConverter))]
public bool Audited { get; set; }
[MaxLength(255)]
[Grid.Column("Comment", TypeName = "varchar", HiddenFromNavigation = true)]
public string Comment { get; set; }
[Grid.Column("CreatedOn", TypeName = "date", Label = "Created On", FormatterType = Grid.FormatterType.date, Alignment = Grid.Position.center, Width = 75, Hidden = true, HiddenFromNavigation = true)]
public DateTime? CreatedOn { get; set; }
[Grid.Column("IsDeleted", TypeName = "bit", Hidden = true, Default = false, HiddenFromNavigation = true)]
public bool is_deleted { get; set; }
#endregion
#region constructor
public Contract()
{
Members = new HashSet<ContractMember>();
PricingTiers = new HashSet<TierMatrix>();
Terms = new HashSet<ContractDetail>();
}
#endregion
//Status _status = null;
//public virtual Status Status { get { return _status; } set { StatusID = value.IsNotNull(oObject => oObject.ID, StatusID); _status = value; } }
[JsonIgnore]
public virtual ICollection<ContractMember> Members { get; set; }
public virtual ICollection<ContractMemberDetail> MemberDetails { get; set; }
[JsonIgnore]
public virtual ICollection<TierMatrix> PricingTiers { get; set; }
[JsonIgnore]
public virtual ICollection<ContractDetail> Terms { get; set; }
}
配置:
class ContractConfiguration
: EntityTypeConfiguration<Models.Contract>
{
internal ContractConfiguration(string table, string schema = "dbo")
{
ToTable(table, schema);
HasKey(Model => Model.ID);
Property(Model => Model.ID)
.HasColumnName("ContractID")
.HasColumnType("int")
.HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
Property(Model => Model.ContractDesc)
.HasColumnName("ContractDesc")
.HasColumnType("varchar")
.IsOptional()
.HasMaxLength(100);
Property(Model => Model.ContractType)
.HasColumnName("ContractType")
.HasColumnType("varchar")
.IsRequired()
.HasMaxLength(100);
Property(Model => Model.Audited)
.HasColumnName("Audited")
.HasColumnType("bit")
.IsRequired();
Property(Model => Model.Comment)
.HasColumnName("Comment")
.HasColumnType("varchar")
.IsOptional()
.HasMaxLength(255);
Property(Model => Model.CreatedOn)
.HasColumnName("CreatedOn")
.HasColumnType("smalldatetime")
.IsRequired();
Property(Model => Model.CorrelationID)
.HasColumnName("CorrelationID")
.HasColumnType("uniqueidentifier")
.IsOptional();
Property(Model => Model.is_deleted)
.HasColumnName("IsDeleted")
.HasColumnType("bit")
.IsRequired();
HasMany(Model => Model.Members)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.PricingTiers)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.Terms)
.WithRequired(Model => Model.Contract);
}
}
模型生成器:
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new Configurations.ContractConfiguration("Contract", Common.Schema.contract_management));
}
观察这个变量:
Context().Set(typeof(Models.Contract)).ToString()
生成以下内容:
SELECT
[Extent1].[ContractID] AS [ContractID],
[Extent1].[CorrelationID] AS [CorrelationID],
[Extent1].[ContractDesc] AS [ContractDesc],
[Extent1].[ContractType] AS [ContractType],
[Extent1].[Audited] AS [Audited],
[Extent1].[Comment] AS [Comment],
[Extent1].[CreatedOn] AS [CreatedOn],
[Extent1].[IsDeleted] AS [IsDeleted],
[Extent1].[Contract_ID] AS [Contract_ID] //<--- this is what does not belong
FROM [cm].[Contract] AS [Extent1]
我查看了 table 的数据库删除和创建脚本,但 Contract_ID 没有出现在其中。我检查了与此 table 相关的所有外键,并确保它们是 ContractID 而不是 Contract_ID。文本 Contract_ID 也没有出现在解决方案代码库中的任何位置。我们在这个数据库上也没有任何触发器 table.
我 运行 没有地方签入代码。我正在考虑一个创可贴,它将创建一个名为 Contract_ID 的计算列,该列反刍主键值。如果有人能告诉我在哪里看,那就太棒了。
好吧,我终于从头开始重建了 C# 模型,我找到了额外列的原因,问题出在外键映射中
[JsonIgnore]
public virtual ICollection<ContractMember> Members { get; set; }
[JsonIgnore]
public virtual ICollection<ContractMemberDetail> MemberDetails { get; set; }
[JsonIgnore]
public virtual ICollection<TierMatrix> PricingTiers { get; set; }
[JsonIgnore]
public virtual ICollection<ContractDetail> Terms { get; set; }
位于 C# 模型上。
原来是从契约模型的角度映射这个。
HasMany(Model => Model.Members)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.MemberDetails)
.WithOptional(Model => Model.Contract);
HasMany(Model => Model.PricingTiers)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.Terms)
.WithRequired(Model => Model.Contract);
从这四种模型的角度消除了映射集合的需要。实际上包括 Member、MemberDetails、PricingTiers 和 Terms 上的外键映射。当找到 none 时,框架逻辑决定它需要合同模型上的 Contract_ID 列,对 EF 做了一些事情。
我有这样一种情况,entity framework 正在向合同模型添加一个 contract_id 列,而该列在 C# 模型中不作为 属性 存在,而且它不存在在数据库中。我已经梳理了数据库和解决方案,以供参考'contract_id',我正在为这个而绞尽脑汁。
[Export(typeof(IModel))]
[Grid.GridNavigator(cloneToTop = true, add = true, del = true, refresh = true, refreshstate = Grid.RefreshState.current, addfunc = "$.modules.grids.contract.add")]
[Grid.Events(serializeGridData = "$.modules.grids.common.serialize")]
public class Contract
: Model
, ILogicalDelete
{
#region properties
[Key]
[Grid.Column("ContractID", TypeName = "int", Label = "Contract ID", Width = 75, VisibleTo = new Type[] { typeof(Contract) })]
[Grid.Search(SearchOperators.equal)]
[Grid.Controls.Hidden]
public override int ID { get { return base.ID; } set { base.ID = value; } }
[Grid.Column("CorrelationID", Hidden = true)]
[Grid.Controls.Hidden]
public Guid? CorrelationID { get; set; }
//[Grid.Column("StatusID", ModelNavigation = "Status", HiddenFromNavigation = true)]
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
//public int StatusID { get; set; }
[MaxLength(100)]
[Grid.Column("ContractDesc", TypeName = "varchar", Label = "Description")]
[Grid.Search(SearchOperators.begins_with | SearchOperators.contains | SearchOperators.ends_with)]
[Grid.Controls.CustomEditable(Grid.ControlType.autocomplete, Url = "/api/contractservice/list?name=contract&column=ContractDesc&_type={0}", KeyField = "ID", TextField = "ContractDesc", ForReferenceUse = true)]
public string ContractDesc { get; set; }
[MaxLength(100)]
[Grid.Column("ContractType", TypeName = "varchar", Label = "Type", VisibleTo = new Type[] { typeof(Contract) }, HiddenFromNavigation = true)]
[Grid.Search(Grid.SearchType.select, url = "/api/contractservice/list?name=ContractType", build = "$.services.grid.ctrls.select.build")]
//[Grid.Controls.Select(Url = "/api/contractservice/list?name=ContractType", BuildSelect = "$.services.grid.ctrls.select.build")]
public string ContractType { get; set; }
[Grid.Column("Audited", TypeName = "bit", FormatterType = Grid.FormatterType.checkbox, Alignment = Grid.Position.center, Width = 50, HiddenFromNavigation = true)]
[JsonConverter(typeof(Grid.Serialization.BooleanConverter))]
public bool Audited { get; set; }
[MaxLength(255)]
[Grid.Column("Comment", TypeName = "varchar", HiddenFromNavigation = true)]
public string Comment { get; set; }
[Grid.Column("CreatedOn", TypeName = "date", Label = "Created On", FormatterType = Grid.FormatterType.date, Alignment = Grid.Position.center, Width = 75, Hidden = true, HiddenFromNavigation = true)]
public DateTime? CreatedOn { get; set; }
[Grid.Column("IsDeleted", TypeName = "bit", Hidden = true, Default = false, HiddenFromNavigation = true)]
public bool is_deleted { get; set; }
#endregion
#region constructor
public Contract()
{
Members = new HashSet<ContractMember>();
PricingTiers = new HashSet<TierMatrix>();
Terms = new HashSet<ContractDetail>();
}
#endregion
//Status _status = null;
//public virtual Status Status { get { return _status; } set { StatusID = value.IsNotNull(oObject => oObject.ID, StatusID); _status = value; } }
[JsonIgnore]
public virtual ICollection<ContractMember> Members { get; set; }
public virtual ICollection<ContractMemberDetail> MemberDetails { get; set; }
[JsonIgnore]
public virtual ICollection<TierMatrix> PricingTiers { get; set; }
[JsonIgnore]
public virtual ICollection<ContractDetail> Terms { get; set; }
}
配置:
class ContractConfiguration
: EntityTypeConfiguration<Models.Contract>
{
internal ContractConfiguration(string table, string schema = "dbo")
{
ToTable(table, schema);
HasKey(Model => Model.ID);
Property(Model => Model.ID)
.HasColumnName("ContractID")
.HasColumnType("int")
.HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity);
Property(Model => Model.ContractDesc)
.HasColumnName("ContractDesc")
.HasColumnType("varchar")
.IsOptional()
.HasMaxLength(100);
Property(Model => Model.ContractType)
.HasColumnName("ContractType")
.HasColumnType("varchar")
.IsRequired()
.HasMaxLength(100);
Property(Model => Model.Audited)
.HasColumnName("Audited")
.HasColumnType("bit")
.IsRequired();
Property(Model => Model.Comment)
.HasColumnName("Comment")
.HasColumnType("varchar")
.IsOptional()
.HasMaxLength(255);
Property(Model => Model.CreatedOn)
.HasColumnName("CreatedOn")
.HasColumnType("smalldatetime")
.IsRequired();
Property(Model => Model.CorrelationID)
.HasColumnName("CorrelationID")
.HasColumnType("uniqueidentifier")
.IsOptional();
Property(Model => Model.is_deleted)
.HasColumnName("IsDeleted")
.HasColumnType("bit")
.IsRequired();
HasMany(Model => Model.Members)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.PricingTiers)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.Terms)
.WithRequired(Model => Model.Contract);
}
}
模型生成器:
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new Configurations.ContractConfiguration("Contract", Common.Schema.contract_management));
}
观察这个变量: Context().Set(typeof(Models.Contract)).ToString()
生成以下内容:
SELECT
[Extent1].[ContractID] AS [ContractID],
[Extent1].[CorrelationID] AS [CorrelationID],
[Extent1].[ContractDesc] AS [ContractDesc],
[Extent1].[ContractType] AS [ContractType],
[Extent1].[Audited] AS [Audited],
[Extent1].[Comment] AS [Comment],
[Extent1].[CreatedOn] AS [CreatedOn],
[Extent1].[IsDeleted] AS [IsDeleted],
[Extent1].[Contract_ID] AS [Contract_ID] //<--- this is what does not belong
FROM [cm].[Contract] AS [Extent1]
我查看了 table 的数据库删除和创建脚本,但 Contract_ID 没有出现在其中。我检查了与此 table 相关的所有外键,并确保它们是 ContractID 而不是 Contract_ID。文本 Contract_ID 也没有出现在解决方案代码库中的任何位置。我们在这个数据库上也没有任何触发器 table.
我 运行 没有地方签入代码。我正在考虑一个创可贴,它将创建一个名为 Contract_ID 的计算列,该列反刍主键值。如果有人能告诉我在哪里看,那就太棒了。
好吧,我终于从头开始重建了 C# 模型,我找到了额外列的原因,问题出在外键映射中
[JsonIgnore]
public virtual ICollection<ContractMember> Members { get; set; }
[JsonIgnore]
public virtual ICollection<ContractMemberDetail> MemberDetails { get; set; }
[JsonIgnore]
public virtual ICollection<TierMatrix> PricingTiers { get; set; }
[JsonIgnore]
public virtual ICollection<ContractDetail> Terms { get; set; }
位于 C# 模型上。
原来是从契约模型的角度映射这个。
HasMany(Model => Model.Members)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.MemberDetails)
.WithOptional(Model => Model.Contract);
HasMany(Model => Model.PricingTiers)
.WithRequired(Model => Model.Contract);
HasMany(Model => Model.Terms)
.WithRequired(Model => Model.Contract);
从这四种模型的角度消除了映射集合的需要。实际上包括 Member、MemberDetails、PricingTiers 和 Terms 上的外键映射。当找到 none 时,框架逻辑决定它需要合同模型上的 Contract_ID 列,对 EF 做了一些事情。