【问题标题】:Foreach statement cannot operate on variables of type '?' because '?' does not contain a public definition for 'GetEnumerator'Foreach 语句不能对“?”类型的变量进行操作因为 '?'不包含“GetEnumerator”的公共定义
【发布时间】:2016-11-24 05:11:45
【问题描述】:

我对正在使用的数据库的新副本进行了一些更新,并从数据库生成了 edmx 文件,我修复了几个给我带来问题的存储过程,但是在这种方法中我不断收到此错误

错误 CS1579 foreach 语句无法对“?”类型的变量进行操作因为 '?'不包含“GetEnumerator”的公共定义

我认为它与这个错误有关

错误 CS1936 找不到源类型“int”的查询模式的实现。未找到“选择”

我已经四处寻找解决方案,但没有真正找到任何可靠的解决方案。

我的 DAL 中引发错误的方法是

public List<NewCustomer> GetCustomerToEditByID(int id)
    {
        ExoEntities = new ExoEntities();
        List<NewCustomer> lst = new List<NewCustomer>();

        var query = from a in  ExoEntities.usp_GetCustomerByID(id)
                    select a;

        foreach (var b in query)
        {
            lst.Add(new NewCustomer
            {
                CustomerID = b.CustomerID,
                FirstName = b.FirstName,
                LastName = b.LastName,
                YearBuilt = b.YearBuilt,
                Line1 = b.Line1,
                Line2 = b.Line2,
                City = b.City,
                ZipCode = b.ZipCode,
                StateID = (int)b.StateID,
                StateName = b.StateName,
                County = b.County,
                SubDivisionID = (int)b.SubDivisionID,
                ContactName = b.ContactName,
                Phone = b.Phone,
                OtherPhone = b.OtherPhone,
                Cell = b.Cell,
                Fax = b.Fax,
                Email = b.Email
            });
        }

        return lst;
    }

数据类是

public class NewCustomer
    {
        public int CustomerID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string DateCreated { get; set; }
        public int CreatedBy { get; set; }
        public string YearBuilt { get; set; }
        public byte IsActive { get; set; }
        public int CustomerTypeID { get; set; }

        // Address
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string Line3 { get; set; }
        public string City { get; set; }
        public string ZipCode { get; set; }
        public int StateID { get; set; }
        public string StateName { get; set; }
        public string County { get; set; }
        public int SubDivisionID { get; set; }

        // Contact
        public string ContactName { get; set; }
        public string Phone { get; set; }
        public string OtherPhone { get; set; }
        public string Cell { get; set; }
        public string Pager { get; set; }
        public string Fax { get; set; }
        public string Email { get; set; }
        public byte ContactIsActive { get; set; }
    }

这是存储过程的 EF 上下文类

public virtual int usp_GetCustomerByID(Nullable<int> customerID)
    {
        var customerIDParameter = customerID.HasValue ?
            new ObjectParameter("CustomerID", customerID) :
            new ObjectParameter("CustomerID", typeof(int));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("usp_GetCustomerByID", customerIDParameter);
    }

我的存储过程是

    Create procedure [dbo].[usp_GetCustomerByID]
(
    @CustomerID int
)
AS
SET NOCOUNT OFF
SET TRANSACTION ISOLATION LEVEL READ COMMITTED

DECLARE @ERROR_SEVERITY int,
        @MESSAGE varchar(1000),
        @ERROR_NUMBER int,
        @ERROR_PROCEDURE nvarchar(200),
        @ERROR_LINE int,
        @ERROR_MESSAGE nvarchar(4000);

begin try
    select 
          caxref.CustomerID,
          caxref.AddressID,
          customer.FirstName,
          customer.LastName,
          customer.YearBuilt,
          address.Line1,
          address.Line2,
          address.City,
          address.ZipCode,
          address.StateID,
          address.County,
          state.StateName,
          address.SubDivisionID,
          contact.ContactName,
          contact.Phone,
          contact.OtherPhone,
          contact.Cell,
          contact.Fax,
          contact.Email
    from [CustomerAddressXREF] caxref
        left join [Customer] customer on customer.CustomerID = caxref.CustomerID
        left join [Address] address on address.AddressID = caxref.AddressID
        left join [SubDivision] subdivision on subdivision.SubDivisionID = address.SubDivisionID
        left join [CustomerContactXREF] ccxref on ccxref.CustomerID = customer.CustomerID
        left join [Contact] contact on contact.ContactID = ccxref.ContactID
        inner join [State] state on state.StateID = address.StateID
    where customer.CustomerID = @CustomerID

end try
BEGIN CATCH
    SET @ERROR_SEVERITY = ISNULL(ERROR_SEVERITY(),'');
    SET @ERROR_NUMBER = ISNULL(ERROR_NUMBER(),'');
    SET @ERROR_PROCEDURE = ISNULL(ERROR_PROCEDURE(),''); 
    SET @ERROR_LINE = ISNULL(ERROR_LINE(),'');
    SET @ERROR_MESSAGE = ISNULL(ERROR_MESSAGE(),'');

    -- Test if the transaction is uncommittable.
    IF (XACT_STATE()) = -1
        BEGIN
            --PRINT N'The transaction is in an uncommittable state. Rolling back transaction.'
            ROLLBACK TRANSACTION;
        END;

    -- Test if the transaction is active and valid.
    IF (XACT_STATE()) = 1
        BEGIN
            --PRINT N'The transaction is committable. Committing transaction.'
            COMMIT TRANSACTION;   
        END;

    SET @MESSAGE = 'Error Occured in Stored Procedure ' + cast(@ERROR_PROCEDURE as varchar(200)) + 
                    '; Line Number ' + cast(@ERROR_LINE as varchar) + 
                    '; Message: [' + cast(@ERROR_NUMBER as varchar) + '] - '
                    + cast(@ERROR_MESSAGE as varchar(255))

    RAISERROR(@MESSAGE, @ERROR_SEVERITY, 1);
END CATCH;

我已经在 SSMS 中测试了存储过程,它返回了我需要的所有数据

所以我不确定问题出在哪里。

我已经删除了几次我的 EDMX 文件并从数据库中重新生成了它,但这不起作用,我仍然遇到这 2 个错误。它可能对解决方案非常明显,但它并没有出现在我身上

【问题讨论】:

  • 尝试将SET NOCOUNT OFF 转换为SET NOCOUNT ON,然后重新生成。我真的希望这不会解决它,因为这意味着 EF 正在做一些非常愚蠢的事情(即,使用产生的单个整数作为返回类型),但我之前已经看到其他软件犯过这个错误。
  • @JeroenMostert,不,那没用

标签: c# entity-framework


【解决方案1】:

您的usp_GetCustomerByID C# 函数返回单个int 值,而不是对象集合,因此您不能将其用作查询源。 from a in ExoEntities.usp_GetCustomerByID(id) 无效。

如果要查询usp_GetCustomerByID的返回类型应该是IEnumerable&lt;sometype&gt;。您可能我可以使用IEnumerable&lt;NewCustomer&gt; 作为返回类型,但不清楚这是否是您的实体类型。这样您就不必迭代它并创建新的 NewCustomer 对象。你可以打电话给return usp_GetCustomerByID(id).ToList()

另外,查询from a in &lt;source&gt; select a 本质上是在&lt;source&gt; 上返回一个迭代器,因此您可以使用:

foreach (var b in <source>)

【讨论】:

  • 我很困惑,我有其他方法以这种方式设置并且它们没有抛出任何错误。例如,我有一个 GetVendorByID(id),它工作正常,几乎与 edmx 上下文类中的 usp_GetCustomerByID(id) 相同。我尝试将其创建为 IEnumerable,但没有成功,并尝试按照您提到的方式将其返回,但这引发了错误
  • @Chris GetVendorByID 返回 int?没有办法枚举或查询单个值,所以我看不出它是如何工作的。如果您有一个确实有效的示例,请发布一个完整的、可验证的示例。
  • 实际上usp_GetVendorByID返回一个ObjectResult是有区别的。我不明白为什么 GetCustomerByID 没有返回 ObjectResult,因为在 ssms 中执行存储过程时,它返回的不仅仅是 ID
  • 应该返回ObjectResult,或者至少不返回int。你是写了那个 C# 函数还是生成了它?如果它是生成的,请检查设计器中的属性,以便它返回正确的类型。
  • 我写了那个方法,上下文的东西是自动生成的。我从模型和 model.store 中删除了存储过程并重新读取,现在它返回一个 ObjectResult
猜你喜欢
  • 1970-01-01
  • 2017-03-08
  • 2016-03-27
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多