简体   繁体   English

外键出现问题并使用EF插入记录

[英]Trouble with foreign key and inserting record with EF

I have the following classes: 我有以下课程:

public class Instrument
{
    public int Id { get; set; }
    public string Book { get; set; }
    public string Page { get; set; }
}
public class Order
{
    public int Id { get; set; }
    public string OrderName { get; set; }
    public ICollection<MatchedInstrument> MatchedInstruments { get; set; }
}
public class MatchedInstrument
{
    public int Id { get; set; }
    //public int InstrumentId { get; set; }
    public Instrument Instrument { get; set; }
    public bool IsIncluded { get; set; }
    public string Notes { get; set; }
}

And the following EF DbContext: 以及以下EF DbContext:

    public class AppContext : DbContext
{
    public DbSet<Instrument> Instruments { get; set; }
    public DbSet<Order> Orders { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>().HasKey(o => o.Id)
           .HasMany(o => o.MatchedInstruments)
           .WithMany().Map(m => 
           {
              m.MapLeftKey("orderid");
              m.MapRightKey("selectedmatchid");
              m.ToTable("ordermatchedinstruments");
           });

        modelBuilder.Entity<MatchedInstrument>().HasKey(m => m.Id)
           .HasRequired(m => m.Instrument)
           .WithRequiredPrincipal();
   }
}

Note that the OrderMatchedInstruments table is a join table that simply contains two columns: orderid and matchedinstrumentid (relating to the MatchedInstruments table). 请注意, OrderMatchedInstruments表是一个联接表,仅包含两列:orderid和matchedinstrumentid(与MatchedInstruments表相关)。 The schema for the MatchedInstruments table looks like this: MatchedInstruments表的模式如下所示:

[dbo].[MatchedInstruments](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [IsIncluded] [bit] NOT NULL,
    [Notes] [varchar](max) NULL,
    [InstrumentId] [int] NOT NULL

This all seems to work fine for querying data. 这一切似乎都可以很好地用于查询数据。 I am able to query an order and include its matched instruments. 我能够查询订单并包括其匹配的工具。

However, when I try to add a new MatchedInstrument to an order, I get an error telling me that InstrumentId cannot be null in the MatchedInstrument table. 但是, 当我尝试向订单中添加新的MatchInstrument时,出现一条错误消息,告诉我InstrumentId在MatchInstrument表中不能为null。

...
// Demo Code - count on non-null objects
var instrument = _context.Instruments.FirstOrDefault(); 
var order = _context.Orders.SingleOrDefault(o => o.Id == 5);
order.MatchedInstruments.Add(new MatchedInstrument() { Instrument = instrument });
_context.SaveChanges();    

This leads me to think I need to add an InstrumentId property to the MatchedInstrument class. 这使我认为我需要向MatchedInstrument类添加InstrumentId属性。 However, I thought that EF worked fine without having the foreign key as long as it held to the appropriate naming conventions. 但是,我认为只要遵循适当的命名约定,EF就可以在没有外键的情况下正常工作。 IOW, the fact that I have navigation property of Instrument would lead me to think that it would automatically look in the table for InstrumentId and would therefore populate that for me. IOW,我具有Instrument的导航属性这一事实使我认为它会自动在表中查找InstrumentId,因此会为我填充它。

Is this not the case or am I missing something in regards with how EF deals with foreign keys? 是不是这样,或者我在EF如何处理外键方面缺少某些东西?

将以下属性添加到模型中的每个ID属性:

[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]

I just got this to work. 我刚刚得到这个工作。 I had set up my relationship incorrectly in my mapping. 我在映射中建立的关系不正确。 I changed from using WithRequiredPrincipal to the following: 我从使用WithRequiredPrincipal更改为以下内容:

    modelBuilder.Entity<MatchedInstrument>().HasKey(m => m.Id)
       .HasRequired(m => m.Instrument)
       .WithMany().HasForeignKey(m => m.InstrumentId);

Not sure why I thought I needed to use WithRequiredPrincipal(), but that definitely fixed my issue. 不知道为什么我认为我需要使用WithRequiredPrincipal(),但这肯定解决了我的问题。

As I see you are not sending the InstrumentId, but the object Instrument, this is the cause of your problem, because you schema has InstrumentId as a Not Null Integer and what you are sending is the entire Instrument Object, you just need to be sure of what data you really need and then change your code. 如我所见,您发送的不是InstrumentId,而是对象Instrument,这是造成问题的原因,因为您的架构将InstrumentId作为Not Null整数,并且您发送的是整个Instrument对象,因此您只需要确保您真正需要什么数据,然后更改代码。

Grettings...Ing. Grettings ... Ing。 Jorge Pérez Bárcenas 豪尔赫·佩雷斯·巴尔恰纳斯

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM