比较两个模型共享数据类型

时间:2017-10-22 15:41:00

标签: c# asp.net-mvc linq asp.net-mvc-5

Heello,我试图比较两个模型中的两个共享数据类型值:

目标 -

    public int Id { get; set; }
    public DateTime StartDate  { get; set; }
    public  DateTime? EndDate { get; set; }
    public string Type { get; set; }
    public double Level { get; set; }
    public bool Achieved { get; set; }

和     距离:

 public class Distance
{
    public int Id { get; set; }
    public double DistanceRun { get; set; }
    public DateTime _Date { get; set; }
    public String AdditionalComments { get; set; }
}

这是我的代码,用于比较两个日期(目标)之间的距离。

public ActionResult AchievedGoals(string type)
    {
        var goals = db.Goals.Where(x => x.EndDate != null).AsEnumerable();
        List<Distance> distances = new List<Distance>();
        foreach (var goal in goals)
        {
            var goalsBetween = db.Distances.Where(x => x._Date.Date.CompareTo(goal.StartDate) > 0 & x._Date.Date.CompareTo(goal.EndDate) < 0);
            Distance d = (Distance) goalsBetween;
            distances.Add(d);
        }

        return View(distances.ToList());
    }

我在

上收到错误
   Distance d = (Distance) goalsBetween;

说出这个错误

System.InvalidCastException:&#39;无法转换类型&System; System.Data.Entity.Infrastructure.DbQuery`1 [WAD_Tracker.Models.Distance]&#39;输入&#39; WAD_Tracker.Models.Distance&#39;。&#39;

这里的观点也是:

 @model IEnumerable<WAD_Tracker.Models.Goals>

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
    <th>
        @Html.DisplayNameFor(model => model.StartDate)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.EndDate)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Type)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Level)
    </th>
    <th>
        @Html.DisplayNameFor(model => model.Achieved)
    </th>
    <th></th>
</tr>

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.StartDate)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.EndDate)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Type)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Level)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Achieved)
    </td>
    <td>
        @Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
        @Html.ActionLink("Details", "Details", new { id=item.Id }) |
        @Html.ActionLink("Delete", "Delete", new { id=item.Id })
    </td>
</tr>
}

</table>

2 个答案:

答案 0 :(得分:0)

表达式db.Distances.Where(x => x._yourWhereClause)将返回IQueryable个对象的集合(特别是Distance)。但是在下一行中,您尝试将其转换为单个Distance对象,

 Distance d = (Distance) goalsBetween;

因此你得到了错误!您无法将集合强制转换为单个对象。

您无需转换为单个对象。您应该在IQueryable集合上调用ToList()方法,该方法将为您提供Distance对象列表,并使用AddRange方法将该列表添加到distances列表中。

var distanceList= db.Distances
                    .Where(yourWhereClausePredicate)
                   .ToList();
distances.AddRanges(distanceList);

要比较LINQ查询中Date属性的DateTime值,您应该使用DbFunctions.TruncateTime方法。

var distanceList= db.Distances
                    .Where(f => DbFunctions.TruncateTime(f._Date) 
                                         <= DbFunctions.TruncateTime(goal.EndDate)
                                &&  DbFunctions.TruncateTime(f._Date) 
                                         >= DbFunctions.TruncateTime(goal.StartDate)
                          )
                   .ToList();
distances.AddRanges(distanceList);

请记住,在循环的每次迭代中调用ToList()将执行LINQ查询(调用db)以获取结果。如果您的循环大小很大,我会建议将所有内容读取到本地缓存并查询。再次,测量性能并根据您的情况使用最佳选择。

答案 1 :(得分:0)

错误告诉您问题:您无法将DbQuery投射到Distance。 您目前正在尝试投放准备好的查询&#34;直接进入一个对象。你不能这样做。你需要&#34;执行&#34;查询。请尝试使用此行代替

var goalsBetween = db.Distances.Where(x => x._Date.Date.CompareTo(goal.StartDate) > 0 & x._Date.Date.CompareTo(goal.EndDate) < 0).FirstOrDefault();

您的代码似乎是在列表中添加多个距离。对你而言,你应该&#34;执行&#34;您的查询请使用.ToList().ToEnumerable(),而不是

var goalsBetween = db.Distances.Where(x =&gt; x._Date.Date.CompareTo(goal.StartDate)&gt; 0&amp; x._Date.Date.CompareTo(goal.EndDate)&lt; 0)。 ToList()。选择(g =&gt;(距离)g);

最后select来电只会将列表中的每个项目投放到Distance

然后你可以使用`addRange&#34;将它们添加到distances;如下:

var goalsBetween = db.Distances.Where(x => x._Date.Date.CompareTo(goal.StartDate) > 0 & x._Date.Date.CompareTo(goal.EndDate) < 0).ToList().Select(g => (Distance)g);
distances.AddRange(goalsBetween);