开发者

Linq lambda join error

开发者 https://www.devze.com 2023-03-10 11:46 出处:网络
I have been following the book Pro ASP.net MVC 2 Framework, which I have found to be quite brilliant. But it\'s a real learning curve and now I\'m stuck.

I have been following the book Pro ASP.net MVC 2 Framework, which I have found to be quite brilliant. But it's a real learning curve and now I'm stuck.

In the book you build something like the below, which allows for paging.

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) 

} 

I think needed to adapt this, so that I could do a join on the search

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) 

} 

...but immediately I get an intellisense error saying - Cannot implicitly convert type 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.IList<MeetingRoom.Domain.Entities.Room>'. An explicit conversion exists (are you missing a cast?)

I obviously don't understand the code well enough to figure out what is wrong. I'm also feeling a bit out of my depth with this lamda linq stuff

Room is a domain object which is defined as:

   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开发者_StackOverflow.Domain.entities.RoomCoordinate RoomCoordinate { get; set; }
      }
    }

and represents my Room table. Do I need some sort of parent entity that would represent the join between the Room and Room-co-ordinates table?

The co-ordinates entity looks like this:

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; }  
    }
}

The RoomsListViewModel looks like follows: namespace MeetingRoomsMVC.WebUI.Models { public class RoomsListViewModel { public IList RoomsWithCoordinates { get; set; } public PagingInfo PagingInfo { get; set; }

} }


The problem is, in this code

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

you're constructing an IEnumerable of anonymous-type objects: (room, roomCoordinate) => new { RoomCoordinate = roomCoordinate, Room = room }

And then, in the next line you're trying to assing it to a list of Room.

The problem can be resolved by initially creating an IEnumerable of the correct item type:

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

(note the class name in the lambda).


Here's my suggestion based on the OP's further description:

1) Create an aggregate class that holds both Room and RoomCoordinates info:

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

2) Modify your controller action as follows:

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) Modify your RoomsListViewModel class and your view to reflect these changes.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号