【问题标题】:Linq lambda join errorLinq lambda 连接错误
【发布时间】:2011-09-09 04:39:06
【问题描述】:

我一直在关注 Pro ASP.net MVC 2 Framework 这本书,我发现它非常出色。但这是一个真正的学习曲线,现在我被卡住了。

在本书中,您构建了如下所示的内容,它允许分页。

public ViewResult List([DefaultValue(0)] string cityzip, [DefaultValue(1)] int page)
{

var roomsToShow = roomsRepository.Rooms.Where(x => x.CountryID == cityzip);

var viewModel = new RoomsListViewModel
{

    Rooms = roomsToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(),
    PagingInfo = new PagingInfo
    {
        CurrentPage = page,
        ItemsPerPage = PageSize,
        TotalItems = roomsToShow.Count()
    }
};
return View(viewModel); // Passed to view as ViewData.Model (or simply Model) 

} 

我认为需要对此进行调整,以便我可以加入搜索

public ViewResult List([DefaultValue(0)] string cityzip, [DefaultValue(1)] int page)
{

var roomsToShow = roomsRepository.Rooms.Join(
                    roomCoordinatesRepository.RoomCoordinates,
                    room => room.RoomID,
                    roomCoordinate => roomCoordinate.RoomID,
                    (room, roomCoordinate) => new { RoomCoordinate = roomCoordinate, Room = room });

var viewModel = new RoomsListViewModel
{

    Rooms = roomsToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(),
    PagingInfo = new PagingInfo
    {
        CurrentPage = page,
        ItemsPerPage = PageSize,
        TotalItems = roomsToShow.Count()
    }
};
return View(viewModel); // Passed to view as ViewData.Model (or simply Model) 

} 

...但是我立即收到一个智能感知错误说- 无法将类型 'System.Collections.Generic.List<AnonymousType#1>' 隐式转换为 'System.Collections.Generic.IList<MeetingRoom.Domain.Entities.Room>'。存在显式转换(您是否缺少演员表?)

我显然对代码理解得不够透彻,无法找出问题所在。我也对这个 lamda linq 的东西感到有点不知所措

Room 是一个域对象,定义为:

   namespace MeetingRoom.Domain.Entities
    {
         [Table(Name = "Rooms")]
         public class Room
         {
            [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)] 
            public int RoomID { get; set; }
            [Column] public string Name { get; set; }
            [Column] public string Description { get; set; }
            [Column] public decimal Price { get; set; }
            [Column] public string Category { get; set; }
            [Column] public string Pcode { get; set; }
            [Column] public int CountryID { get; set; }


            public MeetingRooms.Domain.entities.RoomCoordinate RoomCoordinate { get; set; }
      }
    }

并代表我的 Room 表。我是否需要某种父实体来表示 Room 和 Room-co-ordinates 表之间的连接?

坐标实体如下所示:

namespace MeetingRooms.Domain.entities
{
    [Table(Name = "RoomCoordinate")]
    public class RoomCoordinate
    {
        [Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert, Name = "ID")]
        public int CoordID { get; set; }
        [Column]
        public int RoomID { get; set; }
        [Column]
        public string Coordinates { get; set; }
        [Column]
        public decimal Latitude { get; set; }  
        [Column]
        public decimal Longitude { get; set; }  
    }
}

RoomsListViewModel 如下所示: 命名空间 MeetingRoomsMVC.WebUI.Models { 公共类RoomsListViewModel { 公共 IList RoomsWithCoordinates { 得到;放; } 公共 PagingInfo PagingInfo { 获取;放; }
} }

【问题讨论】:

    标签: c# lambda linq-to-entities


    【解决方案1】:

    这是我根据 OP 的进一步描述提出的建议:

    1) 创建一个包含RoomRoomCoordinates 信息的聚合类:

    public class RoomWithCoordinates
    {
        public Room Room { get; set; }
        public RoomCoordinates Coordinates { get; set; }
    }
    

    2) 修改你的控制器动作如下:

    public ViewResult List([DefaultValue(0)] string cityzip, [DefaultValue(1)] int page)
    {
    
    var roomsToShow = roomsRepository.Rooms.Join(
                        roomCoordinatesRepository.RoomCoordinates,
                        room => room.RoomID,
                        roomCoordinate => roomCoordinate.RoomID,
                        (room, roomCoordinate) => new RoomWithCoordinates{ Coordinates = roomCoordinate, Room = room } );
    
    var viewModel = new RoomsListViewModel
    {
    
        RoomsWithCoordinates = roomsToShow.Skip((page - 1) * PageSize).Take(PageSize).ToList(),
        PagingInfo = new PagingInfo
        {
            CurrentPage = page,
            ItemsPerPage = PageSize,
            TotalItems = roomsToShow.Count()
        }
    };
    return View(viewModel); // Passed to view as ViewData.Model (or simply Model) 
    
    } 
    

    3) 修改您的 RoomsListViewModel 类和您的视图以反映这些更改。

    【讨论】:

    • 谢谢,它似乎有帮助,应用程序现在构建并运行,但是当我单击搜索进入 List 方法时,我收到一个错误:查询包含对定义的项目的引用不同的数据上下文。错误发生在这一行 - var viewModel = new RoomsListViewModel
    • 我已经添加了上面RoomsListViewModel的结构
    • 这可能与我不熟悉的DB框架有关。我认为您需要以某种方式将“RoomWithCoordinates”类注册到数据上下文中,但我无法为此提供准确的指导,抱歉
    • 我认为你是对的,我正在使用 ninject 实现存储库模式,将实体绑定到存储库。我会看看我自己能不能解决这个问题......
    【解决方案2】:

    问题是,在这段代码中

    var roomsToShow = roomsRepository.Rooms.Join(
                    roomCoordinatesRepository.RoomCoordinates,
                    room => room.RoomID,
                    roomCoordinate => roomCoordinate.RoomID,
                    (room, roomCoordinate) => new { RoomCoordinate = roomCoordinate, Room = room });
    

    您正在构建一个匿名类型对象的IEnumerable(room, roomCoordinate) => new { RoomCoordinate = roomCoordinate, Room = room }

    然后,在下一行中,您尝试将其分配给Room 的列表。

    可以通过最初创建正确项目类型的IEnumerable 来解决问题:

    var roomsToShow = roomsRepository.Rooms.Join(
                    roomCoordinatesRepository.RoomCoordinates,
                    room => room.RoomID,
                    roomCoordinate => roomCoordinate.RoomID,
                    (room, roomCoordinate) => new MeetingRoom.Domain.Entities.Room{ RoomCoordinate = roomCoordinate, Room = room });
    

    (注意 lambda 中的类名)。

    【讨论】:

    • 我现在在 (room, roomCoordinate) => new MeetingRoom.Domain.Entities.Room Room = room }) 上遇到错误——错误是—— - 'MeetingRoom.Domain.Entities.Room' 不包含'Room' 的定义 应该创建一个表示连接的新域实体,因此由Rooms 和Room 坐标表/对象组成?
    • 嗯,你的房间类型是一个疯狂的猜测。您能否详细说明您在此操作中到底想做什么?在这种情况下,我可以为你想出一个合适的解决方案
    • 我正在尝试在 Room 表和 Room 坐标表上执行相当于 SQL 选择的操作。我有上面添加的现有域实体。我想将这些列为搜索结果,因此是分页代码。一旦我完成了这项工作,我将需要在其中添加某种 where 子句以将其限制为某些坐标。感谢您对 Zruty 的帮助,非常感谢。
    • 那么你的RoomsListViewModel类需要加入房间坐标信息。目前,您只有 IList Rooms 字段,但您需要修改它。例如,创建一个聚合类 RoomInfoEx{public Room Room{get;set;} public RoomCoordinates Coordinates{get;set;} } 并相应地修改控制器。
    • 我想我会在单独的答案中写下我的建议
    猜你喜欢
    • 2014-05-13
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    相关资源
    最近更新 更多