【问题标题】:Unable to cast the type 'System.Nullable`1' to type 'System.Object' - ASP.NET MVC无法将类型“System.Nullable`1”转换为类型“System.Object”-ASP.NET MVC
【发布时间】:2012-07-05 05:48:04
【问题描述】:

错误

Unable to cast the type 'System.Nullable`1' to type 'System.Object'.
 LINQ to Entities only supports casting Entity Data Model primitive types.

这是我遇到的错误。

控制器 -

 public ActionResult FixturesAll()
 {
     teamMgr = new TeamManager();
     fixtureMgr = new FixtureManager();

     var team = teamMgr.GetTeams();
     var viewModel = new TeamIndexViewModel()
     {
          Teams = team.ToList(),
          NumberOfTeams = team.Count()
     };

     var fixtures = from fixtures in Oritia_entities.Fixtures
                    where fixtures.SeasonId == seasionID
                    select new FixtureModel
                    {

                        Team1 = "",
                        Team2 = "",
                        Winners = (fixtures.TeamWon+""),
                        FirstBattingTeam = (fixtures.FirstBattingTeam+""),
                        SecondBattingTeam = (fixtures.SecondBattingTeam+""),
                        Team1Score = fixtures.Team1Score + "",
                        Team1Wickets = fixtures.Team1Wickets + "",
                        Team2Score = fixtures.Team2Score + "",
                        Team2Wickets = fixtures.Team2Wickets + ""
                    };

      ViewData["Fixtures"] = fixtures;
      return View(viewModel);
 }

局部视图

<%@ Control Language="C#" Inherits=
"System.Web.Mvc.ViewUserControl<IEnumerable<DataAccess.FixtureModel>>" %>
    <table>
    <% foreach (var item in ViewData["Fixtures"]
 as IEnumerable<DataAccess.FixtureModel>) // Here I am getting the error
       { %>
          <tr>                 
            <td>
                <%: item.Team1 %>
            </td>
            <td>
                <%: item.Team2 %>
            </td>
          </tr>
   </table>

查看

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
 Inherits="System.Web.Mvc.ViewPage<FunBox.ViewModels.TeamIndexViewModel>" %>
<ul>
    <% foreach (string team in Model.Teams)
       { %>
           <li><a href="<%: team.ToString() %>/">
           <%: team.ToString()  %></a> </li>
    <% } %>
</ul>

<div>
        <% Html.RenderPartial("FixturesAll",ViewData["Fixtures"]); %>
    </div>

复杂类

 public class TeamIndexViewModel
 {
     public int NumberOfTeams { get; set; }
     public List<String> Teams { get; set; }
 }

 public class FixtureModel
 {
     public string Team1 { get; set; }
     public string Team2 { get; set; }
     public string Winners { get; set; }
     public string Team1Score { get; set; }
     public string Team1Wickets { get; set; }
     public string Team2Score { get; set; }
     public string Team2Wickets { get; set; }
     public string FirstBattingTeam { get; set; }
     public string SecondBattingTeam { get; set; }
 }

sp_help 装置的输出

Id          bigint (pk)
TeamID1     bigint
TeamID2         bigint
TeamWon         bigint
Date            datetime
SeasonId    bigint
ManOfTheMatch   bigint
FirstBattingTeam    bigint
SecondBattingTeam   bigint
ResultDescription   nvarchar
Team1Score  bigint
Team2Score  bigint
Team1Wickets    bigint
Team2Wickets    bigint

这是我的整体结构,我收到了上述错误。我用谷歌搜索,但没有得到确切的解决方案。非常感谢任何帮助。

感谢所有人的帮助,我特别感谢 Jon Skeet 提出的想法

请查看我更新后的查询

 var data = from fixtures in Oritia_entities.Fixtures
                   join t1 in Oritia_entities.Teams on new { ID = fixtures.TeamID1 } equals new { ID = t1.ID }
                   join t2 in Oritia_entities.Teams on new { ID = fixtures.TeamID2 } equals new { ID = t2.ID }
                   where fixtures.SeasonId == seasionID
                   select new FixtureModel
                   {
                       Team1 = t1.TeamName,
                       Team2 = t2.TeamName,

                       Winners = SqlFunctions.StringConvert((double)(fixtures.TeamWon ?? 1)),
                       FirstBattingTeam = SqlFunctions.StringConvert((double)(fixtures.FirstBattingTeam ?? 1)),
                       SecondBattingTeam = SqlFunctions.StringConvert((double)(fixtures.SecondBattingTeam ?? 1)),
                       Team1Score = SqlFunctions.StringConvert((double)(fixtures.Team1Score ?? 1)),
                       Team1Wickets = SqlFunctions.StringConvert((double)(fixtures.Team1Wickets ?? 1)),
                       Team2Score = SqlFunctions.StringConvert((double)(fixtures.Team2Score ?? 1)),
                       Team2Wickets = SqlFunctions.StringConvert((double)(fixtures.Team2Wickets ?? 1))

                   };

我使用SqlFunctions.StringConvert 转换为字符串,现在它可以工作了。谢谢大家。

【问题讨论】:

  • 快速旁注:使用字符串连接将值转换为字符串真的很讨厌。为什么你一开始还要将数字表示为字符串?
  • @JonSkeet 我现在删除了一个条件,以使 SO 中的代码简短。它将使用 a&gt;b?c :d 检查 int 值。当我给出 '.ToString()' 时,会出现编译时问题。
  • 听起来你可以先在表达式周围加上括号......
  • 是的。类似Winners =(fixtures.TeamWon==fixtures.TeamID1?t1.TeamName:t2.TeamName)。有什么问题或其他更好的方法吗?
  • 在这种情况下你不需要括号,也不需要+"",这正是我所抱怨的。

标签: c# asp.net-mvc linq


【解决方案1】:

代替:

<% foreach (var item in ViewData["Fixtures"] as IEnumerable<DataAccess.FixtureModel>)

尝试:

<% foreach (var item in Model)

还可以尝试使用.ToList() 方法急切地加载您的实体:

ViewData["Fixtures"] = fixtures.ToList();

您也可以考虑使用视图模型而不是ViewData。它将使您的代码更加简洁,您将不再依赖 魔术字符串


更新:

试试这个:

var fixtures = Oritia_entities
    .Fixtures
    .Where(f => f.SeasonId == seasionID)
    .ToList()
    .Select(f => new FixtureModel
    {
        Team1 = "",
        Team2 = "",
        Winners = (f.TeamWon+""),
        FirstBattingTeam = (f.FirstBattingTeam+""),
        SecondBattingTeam = (f.SecondBattingTeam+""),
        Team1Score = f.Team1Score + "",
        Team1Wickets = f.Team1Wickets + "",
        Team2Score = f.Team2Score + "",
        Team2Wickets = f.Team2Wickets + ""
    });

【讨论】:

  • 但实际上我又遇到了问题
  • 我猜你的 LINQ 查询有问题。你在那里做的那些字符串连接看起来有点奇怪和臭。
  • @VeeKeyBee,看看我的更新,你可以如何重写你的 LINQ 查询。
【解决方案2】:

尝试重写您的 LINQ 查询:

var fixtures = Oritia_entities.Fixtures
    .Where(fixtures => fixtures.SeasonId == seasionID)
    .AsEnumerable()
    .Select(fixtures => new FixtureModel
                    {

                        Team1 = "",
                        Team2 = "",
                        Winners = (fixtures.TeamWon+""),
                        FirstBattingTeam = (fixtures.FirstBattingTeam+""),
                        SecondBattingTeam = (fixtures.SecondBattingTeam+""),
                        Team1Score = fixtures.Team1Score + "",
                        Team1Wickets = fixtures.Team1Wickets + "",
                        Team2Score = fixtures.Team2Score + "",
                        Team2Wickets = fixtures.Team2Wickets + ""
                    }
    )
    .ToList();

LINQ 查询基本相同,但我在可以转换为 SQL 的最后一个条件之间放置了一个 AsEnumerable() 调用(即 Where(...),以及seasionID 顺便说一句?),以及 Select(...)。

原因是我认为 L2S 试图以某种方式将 Select(..) 转换为 SQL。不确定它是否会起作用,但值得一试。

【讨论】:

    【解决方案3】:

    在控制器中使用它:

      ViewData["Fixtures"] = fixtures.ToArray();
    

    我不确定,但我认为这就是您的问题所在。如果您不使用 ToArray,那么您将向 View 发送 IQueryable,这可能会出现问题。

    【讨论】:

    【解决方案4】:

    试一试...(虽然 id 稍微调整了 try catch,如果你最终使用它。我不建议抑制错误而不做任何事情/让它无声无息地死去; P)

     public string NullableObjectToString(object obj)
     {
          try
          {
              if (obj == null)
                  return "";
    
              return (obj ?? string.Empty).ToString();
          }
          catch (Exception)
          {
              return "";
          }
      }
    

    然后

    var fixtures = from fixtures in Oritia_entities.Fixtures
                      where fixtures.SeasonId == seasionID
                      select new FixtureModel
                      {                        
                         Winners = NullableObjectToString(fixtures.TeamWon),
                         FirstBattingTeam = NullableObjectToString(fixtures.FirstBattingTeam) // ..... you get the idea
                      }
    

    【讨论】:

    • 感谢您的想法。但是有很多内置功能可以执行此操作。请检查我更新的问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2017-05-05
    • 2011-06-22
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多