2016-08-17 85 views
4

我有一個可枚舉實體集合被添加到數據庫,但它似乎需要一些轉換。任何人都可以將我指向正確的方向嗎?如何從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類:

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

} 

更多信息: 上傳包含詳細信息的文件,並將在一個表中創建主記錄。文件中的細節將被添加到一個單獨的表中,第一個表中自動生成masterId。該問題無法將詳細信息添加到數據庫中。

編輯: 我發現了爲什麼出現錯誤。該錯誤是由於該文件的內容。有些行沒有輸入值,最後一行沒有遵循其餘行的格式,因爲它顯示了總行數。感謝所有的幫助!

+1

你使用哪個版本的EF?在EF6中,您可以使用.AddRange方法:context.LeasingSPReadingDetailEntities.AddRange(details); – Developer

+3

你有什麼問題?從我所知道的情況來看,列舉'details'(在'foreach'中)給出'LeasingSPReadingDetailEntity'對象,而不是'IEnumerable ' – slawekwin

+0

你在哪裏得到異常? – RBT

回答

2

@slawekwin評論是答案。但我認爲有一個更好的解決方案,因爲它看起來像你的代碼迭代2x:1st來生成新的Enumerable(浪費內存),第二個將對象添加到上下文。

不妨直接在迭代每一行時添加對象。

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") 
     } 
    ); 
} 

---編輯---

我不知道,但我可以猜測,「賬期」字段既不是INT也不字節。因此,您應該將其作爲字符串檢索,然後將其解析爲新對象。這是我改變的部分:

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

忽略as enumerable有一個編譯錯誤「System.Data.DataTable不包含'GetEnumerator'的pulbic定義,並且它仍然給出無效的轉換異常 – Scar

+0

有用的信息。我編輯了答案 – kurakura88

+0

請看看數據庫中的「Bill Cycle」是什麼。你試圖把它轉換爲int/byte,但我真的懷疑它在開始時是int/byte。如果它是一個字符串,那麼:'BillCycleYear = int.Parse(row.Field (「Bill Cycle」)。Substring(0,4)),'。 BillCycleMonth需要採用同樣的方法。 – kurakura88

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); 
+0

「不包含AddRange的定義」並放入列表仍然會導致無效的轉換異常 – Scar

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 

    } 
+0

我已經完成了以前但改變它,因爲它仍然給予無效的轉場異常。我不確定這裏有什麼問題:\ – Scar

+0

您最近的修改建議您的問題現在已解決。在一天結束時,您教會了我一些非常新的東西,因爲您在運行時收到了錯誤信息。我之前的假設是,編譯器應該能夠在編譯時自己檢測到該類型的不匹配。現在我看到它正在發出警告 - 「可疑的演員:從LeasingSPReadingDetailEntity和System.Collections.Generic.IEnumerable '繼承的解決方案中沒有類型。我將不得不調查這一發現。感謝您的教學! – RBT

相關問題