将一个类型从匿名转换为查询中的其他类型 - 需要保留try / catch块的范围

时间:2017-08-02 13:03:36

标签: c# linq

编辑 - 我真的想要一些反馈,为什么这个问题被投票? 我给了一个工作和非工作版本的代码,显示了我尝试过的所有内容,并迅速回复了建议。 也许你们中的一些人已经忘记了在每一个代表点开始时爬升的速度有多慢。计数!

我愿意改进问题标题。 在C#6

以下代码有效:

DistributionStopInformation stop = new DistributionStopInformation();

stop = (from s in rDb.DistributionStopInformations
                        where s.UniqueIdNo == item.UniqueIdNo
                        select s).First();

但是一旦我不希望所有内容都返回,我就会收到错误消息: Cannot implicitly convert type <anonymous....

像这样:

DistributionStopInformation stop = new DistributionStopInformation();

stop = (from s in rDb.DistributionStopInformations
                          where s.UniqueIdNo == item.UniqueIdNo
                          select new
                          {
                              createdby = s.CreatedBy
                          }).First();

我尝试过创建一个新类并继承自基类,如:

class stopInfo : DistributionStopInformation
{

}
stopInfo stop = new stopInfo();

stop = (from s in rDb.DistributionStopInformations
                          where s.UniqueIdNo == item.UniqueIdNo
                          select new
                          {
                              createdby = s.CreatedBy
                          }).First();

但我得到同样的错误。

在转到这里寻求帮助之前尝试了几件不同的事情......

编辑: 我需要这样做的原因(首先是delcare)是我需要将它包装在try / catch块中 - 显然newItem行将尝试访问超出范围的stop变量。

   try
   {
       var stop = (from s in rDb.DistributionStopInformations
                   where s.UniqueIdNo == item.UniqueIdNo
                   select new
                   {
                       createdby = s.CreatedBy
                   }).First();
   }
   catch (Exception)
   {
       throw;
   }

   newItem.CreatedBy = stop.CreatedBy

编辑: 好的,请求这里是完整的代码 - 在下面的停止超出了下面的范围:

       foreach (var item in newItems)
        {

            //go see if this item exists already
            var itemCheck = (from i in aDb.recent_items where i.item_number == item.ItemNumber select i).ToArray();

            if (itemCheck.Count() == 0)
            {

                //go get the stop

                try
                {
                    stopInfo stop = new stopInfo();

                    var stop = (from s in rDb.DistributionStopInformations
                                where s.UniqueIdNo == item.UniqueIdNo
                                select new
                                {
                                    s.BranchId,
                                    s.RouteCode,
                                    s.StopName,
                                    s.StopAddress,
                                    s.StopCity,
                                    s.StopState,
                                    s.StopZipPostalCode,
                                }).First();
                }
                catch (Exception)
                {

                    throw;
                }
                    //update the counter which will be returned            
               itemCountUpdated++;
                //give em some info so we know its still working...
                Console.WriteLine("Doing number: " + itemCountUpdated);
                //create a new item
                recent_items newItem = new recent_items();

                //grab the info for each property
                newItem.azure_record_created = DateTime.Now;
                newItem.branch_id = stop.BranchId;
                newItem.datatrac_record_created = item.DatetimeCreated;
                if (stop.RouteCode.Length >= 3) { newItem.branch_id_from_route_code = stop.RouteCode.ToString().Substring(0, 3); }
                newItem.datatrac_unique_id_no = item.UniqueIdNo;
                newItem.item_description = item.ItemDescription;
                newItem.item_number = item.ItemNumber;
                newItem.item_sequence = item.ItemSequenceNo;
                newItem.item_weight = item.ExpectedWeight;
                newItem.route_code = stop.RouteCode;
                newItem.stop_address = stop.StopAddress;
                newItem.stop_city = stop.StopCity;
                newItem.stop_name = stop.StopName;
                newItem.stop_state = stop.StopState;
                newItem.stop_zipcode = stop.StopZipPostalCode;

                //add the record to the context
                aDb.recent_items.Add(newItem);

                //if this is the 100th time then write the records

            if (itemCountUpdated % 100 == 0)
                {
                    aDb.SaveChanges();
                }
            }

        }
        //write out any records that are still left
        aDb.SaveChanges();

根据同样的错误尝试了这个建议:

 var stop = new { branchID = "tst" };

                try
                {
                    //stopInfo stop = new stopInfo();

                    stop = (from s in rDb.DistributionStopInformations
                                where s.UniqueIdNo == item.UniqueIdNo
                                select new
                                {
                                    s.BranchId,

                                }).First();
                }
                catch (Exception)
                {

                    throw;
                }

根据另一个建议,我也试过这个:

  try
                {
                    //stopInfo stop = new stopInfo();

                   DistributionStopInformation stop = (from s in rDb.DistributionStopInformations
                                where s.UniqueIdNo == item.UniqueIdNo
                                select new DistributionStopInformation
                                {
                                    s.BranchId,

                                }).First();
                }
                catch (Exception)
                {

                    throw;
                }

但我得到了:

无法使用集合初始值设定项初始化类型'stopInfoClass',因为它没有实现'System.Collections.IEnumerable'

3 个答案:

答案 0 :(得分:3)

如果你必须保持anon类型只包含一个属性,请尝试这个,尽管你不能将stop变量传递给其他方法,因为它是一个匿名类型

var stop = (from s in rDb.DistributionStopInformations
            where s.UniqueIdNo == item.UniqueIdNo
            select new
            {
                createdby = s.CreatedBy
            }).First();

答案 1 :(得分:1)

对于您的具体问题,您可以完全删除try catch(它没有实现任何目标)。只是这样做:

var stop = (from s in rDb.DistributionStopInformations
            where s.UniqueIdNo == item.UniqueIdNo
            select new
            {
                s.BranchId,
                s.RouteCode,
                s.StopName,
                s.StopAddress,
                s.StopCity,
                s.StopState,
                s.StopZipPostalCode,
            }).First();
//update the counter which will be returned            
itemCountUpdated++;
// etc

共享整个方法之前的背景如下......

一种可能的方法是使用匿名类型,然后在事后更新DistributionStopInformation。类似的东西:

var anonStop = (from s in rDb.DistributionStopInformations
    where s.UniqueIdNo == item.UniqueIdNo
    select new { CreatedBy = s.CreatedBy }).First();

var stop = new DistributionStopInformation { CreatedBy = anonStop.CreatedBy };

或者,完全避免使用匿名类型:

var stop = (from s in rDb.DistributionStopInformations
    where s.UniqueIdNo == item.UniqueIdNo
    select new DistributionStopInformation { CreatedBy = s.CreatedBy }).First();

如果您想使用匿名类型(并且根本不使用DistributionStopInformation),那么您需要声明try catch的匿名变量 。类似的东西:

var stop = new { createdby = "a"};

try
{
    stop = (from s in rDb.DistributionStopInformations
                  where s.UniqueIdNo == item.UniqueIdNo
                  select new
                  {
                      createdby = s.CreatedBy

                  }).First();        
}
catch (Exception e)
{
    throw;
}

答案 2 :(得分:0)

编写Select new { ... }时,您正在创建匿名类型的实例。顾名思义,类型没有名称,因此你不能对它做很多事情,特别是你不能从方法中返回它并在调用代码中适当地处理它。此外,你既不能暗示也不能用你想要的类型进行拼写。

但是,您似乎清楚地知道您的查询实际返回的内容,基本上是具有一堆属性的实例。此外,您似乎已经拥有一个包含这些信息的类:stopInfo(请注意,命名约定建议使用StopInfo代替。)

所以你应该使用它:

try
{
    stopInfo stop = (from s in rDb.DistributionStopInformations
                    where s.UniqueIdNo == item.UniqueIdNo
                    select new stopInfo // here you instantiate your class
                    {
                        BranchId = s.BranchId,
                        RouteCode = s.RouteCode,
                        StopName = s.StopName,
                        StopAddress = s.StopAddress,
                        StopCity = s.StopCity,
                        StopState = s.StopState,
                        StopZipPostalCode = s.StopZipPostalCode,
                    }).First();
    }
catch (Exception)
{
    // exception-handling, e.g. logging
    throw;
}

现在你甚至可以在你的try / catch中声明变量 ,并在中设置

stopInfo stop;
try { stop = ... }
catch { ... }