MVC EF6插入多个外键

时间:2018-04-27 11:37:43

标签: c# asp.net-mvc entity-framework asp.net-mvc-5 entity-framework-6

嗨我需要知道如果之前不存在行,如何在EF6中插入带有2个外键的父/子行。我在c#MVC 5中使用MSSQL db使用EF6进行数据库通信。 我有4个表与相应的类。 enter image description here

下一步说明:表格包含列和行。 Row有单元格,但由于一个单元属于列,因此列也有单元格。这意味着一个单元格被行和列阻止(使用外键)。 模型类是:

[Table("TD_Tables")]
public class TD_Table
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int TD_TableId { get; set; }
    public bool Active { get; set; }
    public string Orientation { get; set; }
    public int TenderDefinitionId { get; set; }
    [ForeignKey("TenderDefinitionId")]
    public TenderDefinition TenderDefinition { get; set; }

    public virtual ICollection<TD_Column> Columns { get; set; }
    public virtual ICollection<TD_Row> Rows { get; set; }       
}

[Table("TD_Rows")]
public class TD_Row
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int TD_RowId { get; set; }
    public bool Active { get; set; }
    public int Sort { get; set; }

    public int TD_TableId { get; set; }
    [ForeignKey("TD_TableId")]
    public TD_Table Table { get; set; }

    public virtual ICollection<TD_Cell> Cells { get; set; }        
}

[Table("TD_Columns")]
public class TD_Column
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int? TD_ColumnId { get; set; }
    public bool Active { get; set; }
    public string ColumnName { get; set; }
    public int Sort { get; set; }

    public int TD_TableId { get; set; }
    [ForeignKey("TD_TableId")]
    public TD_Table Table { get; set; }

    public int TD_ColumnTypeId { get; set; }
    [ForeignKey("TD_ColumnTypeId")]
    public TD_ColumnType ColumnType { get; set; }

    public virtual ICollection<TD_Cell> Cells { get; set; }
}

[Table("TD_Cells")]
public class TD_Cell
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int TD_CellId { get; set; }
    public bool Active { get; set; }
    public string CellValue { get; set; }

    public int? TD_ColumnId { get; set; }
    [ForeignKey("TD_ColumnId")]     
    public virtual TD_Column Column { get; set; }

    public int? TD_RowId { get; set; }
    [ForeignKey("TD_RowId")]
    public virtual TD_Row Row { get; set; } 
}

对于插入DB,我正在创建一个包含所有行,列的表模型对象 首先是单元格,然后在一次调用中插入全部创建表模型对象:

{
var model = new TD_Table();
model.Active = true;
//number of columns to create
for(int i =0; i < columnsNum.AsInt(0); i++)
{
    var column = new TD_Column()
    {
        Active = true,
        ColumnName = "", 
        ColumnTypeId = (int)Core.Enums.TD_ColumnType.Text,
        Sort = model.Columns.Count
    };
    model.Columns.Add(column);
}
//number of rows to create
for (int i = 0; i < rowsNum.AsInt(0); i++)
{
    var row = new TD_Row()
    {
        Active = true,
        Sort = i,
        TD_TableId = model.TD_TableId
    };
    for(int c = 0; c < model.Columns.Count; c++)
    {
        var cell = new TD_Cell()
        {
            Active = true,
            CellValue = "",
            TD_ColumnId = model.Columns[c].TD_ColumnId,
            Column = model.Columns[c]               
        };
        model.Columns[c].Cells.Add(cell);
        row.Cells.Add(cell);
    }
    model.Rows.Add(row);
}
// add table model in parent definition model
tender.TenderContent.TenderDefinition.Tables.Add(model);
}

在存储库中,我正在更新现有的父定义并添加新表或使用所有子行更新现有的表:

Tender Update(Tender tender)
    {
        using (var db = new TenderDbContext())
        {
            var t = db.Tenders.
                    Include(x => x.TenderContent).
                    Include(x => x.TenderContent.TenderDefinition).                        
                    //Include(x => x.TenderContent.TenderDefinition.Tables).
                    Include(x => x.TenderContent.TenderDefinition.Tables.Select(y => y.Columns.Select(z => z.Cells))).
                    Include(x => x.TenderContent.TenderDefinition.Tables.Select(y => y.Rows.Select(z => z.Cells))).
                    Include(x => x.TenderContent.Survey).
                    Include(x => x.TenderContent.Survey.Questions).
                    Where(x => x.TenderId == tender.TenderId).FirstOrDefault();

            foreach (var table in tender.TenderContent.TenderDefinition.Tables.Where(x => x.Active))
            {
                var tableId = table.TD_TableId;
                var existingTable = t.TenderContent.TenderDefinition.Tables
                    .Where(c => c.TD_TableId == tableId)
                    .FirstOrDefault();

                if (existingTable != null)
                {
                    db.Entry(existingTable).CurrentValues.SetValues(table);
                    if (table.Columns != null && table.Columns.Any())
                    {
                        foreach (var column in table.Columns.Where(x => x.Active))
                        {
                            var existingColumn = db.TD_Columns.Where(x => x.TD_ColumnId == column.TD_ColumnId).FirstOrDefault();
                            if (existingColumn != null)
                                db.Entry(existingColumn).CurrentValues.SetValues(column);
                            else
                                existingTable.Columns.Add(column);
                        }
                    }
                    if (table.Rows != null && table.Rows.Any())
                    {
                        foreach (var row in table.Rows.Where(x => x.Active))
                        {
                            var existingRow = db.TD_Rows.Where(x => x.TD_RowId == row.TD_RowId).FirstOrDefault();
                            if (existingRow != null)
                            {
                                db.Entry(existingRow).CurrentValues.SetValues(row);
                                foreach (var cell in row.Cells.Where(x => x.Active))
                                {
                                    var cellExisting = db.TD_Cells.Where(q => q.TD_CellId == cell.TD_CellId).FirstOrDefault();
                                    if (cellExisting != null)
                                        db.Entry(cellExisting).CurrentValues.SetValues(cell);
                                    else
                                        row.Cells.Add(cell);
                                }
                            }
                            else
                                existingTable.Rows.Add(row);
                        }
                    }
                }
                else
                    t.TenderContent.TenderDefinition.Tables.Add(table); //insert table with all children
            }                
            db.SaveChanges();
            return t;
        }
    }

我的主要问题是插入新表后例如。 t.TenderContent.TenderDefinition.Tables.Add(table)TD_Cells行重复,RowId值已填充,ColumnId为null且ColumnId值已弹出且RowId为null。因此,如果我想插入10个带有2个外键行和列id的单元格,我只有20个单元格,只有1个键 问题是,当我创建一个单元格时,我在列和行中添加了该单元格,EF不知道如何将该单元格映射为具有2个外键。如果我只添加一个将只有1个密钥填充。任何人都可以找到这里的错误,处理这种情况的最佳方法是什么?

0 个答案:

没有答案