如何从IEnumerable集合中向数据库添加对象?

时间:2016-08-17 05:28:28

标签: c# database entity-framework ienumerable

我有一组可插入的实体要添加到数据库中,但似乎需要进行一些转换。有人能指出我正确的方向吗?

bool InsertDetails(DataTable detailTable, string fileName)
{
    using (SunseapEBTContext context = new SunseapEBTContext())
    {
        if (InsertMaster(fileName))//if creating master record successful
        {                    
            int masterId = GetSPReadingM(m => m.FileName == fileName).SPReadingMasterId; //get MasterID of file uploaded

             var details = detailTable.AsEnumerable().Select(row => new LeasingSPReadingDetailEntity()//new entity from datatable
             {
                //SPReadingId = row.Field<long>("ProductID"),

                        SPReadingMasterId = masterId,
                        BillCycleYear = int.Parse(row.Field<int>("Bill Cycle").ToString().Substring(0, 4)),
                        BillCycleMonth = byte.Parse(row.Field<byte>("Bill Cycle").ToString().Substring(4))

            });
            foreach(IEnumerable<LeasingSPReadingDetailEntity> detail  in details)
            {                       
                context.LeasingSPReadingDetailEntities.AddObject(detail);
            }
            context.SaveChanges();                    
        }
        return true;
    }
}

在foreach循环中,抛出异常

  

CS1503参数1:无法从'System.Collections.Generic.IEnumerable'转换为'SunseapEBT.Domain.BillingModule.LeasingContract.Entity.LeasingSPReadingDetailEntity'

LeasingSPReadingDetailEntity class:

public class LeasingSPReadingDetailEntity
{
    public long SPReadingId { get; set; }
    public int SPReadingMasterId { get; set; }
    public int BillCycleYear { get; set; }
    public byte BillCycleMonth { get; set; }

}

更多信息: 将上载包含详细信息的文件,并在一个表中创建主记录。文件中的详细信息将添加到第一个表中自动生成的masterId的单独表中。问题是无法将详细信息添加到数据库中。

编辑: 我发现了为什么会出错。该错误是由于文件的内容。某些行没有输入值,最后一行没有遵循其余行的格式,因为它显示了总行数。谢谢大家的帮助!

3 个答案:

答案 0 :(得分:2)

将其更改为列表,然后添加项目。

var details = detailTable.AsEnumerable().Select(row => new  LeasingSPReadingDetailEntity()//new entity from datatable
         {
            SPReadingId = row.Field<long>("ProductID"),
            SPReadingMasterId = masterId,
            BillCycleYear = int.Parse(row.Field<int>("Bill Cycle").ToString().Substring(0, 4)),
            BillCycleMonth = byte.Parse(row.Field<byte>("Bill Cycle").ToString().Substring(4)),
        }).ToList();
        foreach(var detail  in details)
        {                       
            context.LeasingSPReadingDetailEntities.Add(detail);
        }

或更好:

var details = detailTable.AsEnumerable().Select(row => new  LeasingSPReadingDetailEntity()//new entity from datatable
         {
            SPReadingId = row.Field<long>("ProductID"),
            SPReadingMasterId = masterId,
            BillCycleYear = int.Parse(row.Field<int>("Bill Cycle").ToString().Substring(0, 4)),
            BillCycleMonth = byte.Parse(row.Field<byte>("Bill Cycle").ToString().Substring(4)),
        }).ToList();

context.LeasingSPReadingDetailEntities.AddRange(details);

答案 1 :(得分:2)

您可以将有问题的foreach循环更改为以下任一项。我更喜欢第一个,因为它不那么冗长。

            foreach(var detail  in details)
            {                       
                context.LeasingSPReadingDetailEntities.AddObject(detail);
            }

OR

            foreach(LeasingSPReadingDetailEntity detail  in details)
            {                       
                context.LeasingSPReadingDetailEntities.AddObject(detail);
            }

如果你看一下foreach循环的语法,第一个构造variableType是存储在集合中的元素的类型(在你的情况下是LeasingSPReadingDetailEntity)而不是类型的集合。你做的是后者,这就是你得到无效的施法错误的原因。

foreach(variableType currentElementBeingIterated in collection){

    //code block to operate on currentElement

  }

答案 2 :(得分:2)

@slawekwin评论就是答案。但我认为有一个更好的解决方案,因为看起来你的代码迭代2x:1st生成新的Enumerable(浪费内存),2nd将对象添加到上下文。

当你迭代每一行时,也可以直接添加对象。

foreach(var row in detailTable.AsEnumerable())
{                       
    context.LeasingSPReadingDetailEntities.AddObject(
        new LeasingSPReadingDetailEntity()//new entity from datatable
        {
           //SPReadingId = row.Field<long>("ProductID"),

           SPReadingMasterId = masterId,
           BillCycleYear = int.Parse(row.Field<string>("Bill Cycle").Substring(0, 4)),
           BillCycleMonth = byte.Parse(row.Field<string>("Bill Cycle").Substring(4)),
           AccountNumber = row.Field<string>("Account No."),
           PeriodStart = row.Field<DateTime>("Period Start"),
           PeriodEnd = row.Field<DateTime>("Period End"),
           TownCouncil = row.Field<string>("Customer Name"),
           Service = row.Field<string>("Service Type"),
           Adjustment = row.Field<string>("Adjustment"),
           Block = row.Field<string>("Blk"),
           AddressLine1 = row.Field<string>("Adress Line 1"),
           AddressLine2 = row.Field<string>("Adress Line 2"),
           AddressLine3 = row.Field<string>("Postal Code"),
           Usage = row.Field<decimal>("Usage"),
           Rate = row.Field<decimal>("Rate"),
           Amount = row.Field<decimal>("Amount")
        }
    );
}

---编辑---

我不确定,但我可以猜到&#34; Bill Cycle&#34; field既不是int也不是byte。因此,您应该将其作为字符串检索,然后将其解析为新对象。这是我改变的部分:

BillCycleYear = int.Parse(row.Field<string>("Bill Cycle").Substring(0, 4)),
BillCycleMonth = byte.Parse(row.Field<string>("Bill Cycle").Substring(4)),