将一个(实体类)映射到多个(dto / viewModels)

时间:2011-04-09 22:14:36

标签: asp.net-mvc entity-framework asp.net-mvc-3 automapper ef-code-first

我正在尝试将有关用户的信息映射到几个dto,但我得到了null异常。基本上,我在几个类之间分配信息的原因是因为在几个视图中我需要共同的信息。所以这就是我最终的结果:

用户实体类

public class User 
{
    public int Id { get; set; }
    public string Nickname { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public float Credits { get; set; }
    public float PromotionalCredits { get; set; }
    public string Telephone { get; set; }
    public string Mobile { get; set; }
    public double RatingAverage { get; set; }
    public string ProfileImage { get; set; } 
    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<Role> Roles { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
    public virtual ICollection<Item> Items { get; set; }
    public virtual ICollection<Bid> Bids { get; set; }
    public virtual ICollection<CreditCard> CreditCard { get; set; }
    public virtual ICollection<Message> ReceivedMessages { get; set; }
    public virtual ICollection<Message> SentMessages { get; set; }
    public virtual ICollection<Item> WatchList { get; set; }
    public virtual ICollection<Rating> OwnRatings { get; set; }
    public virtual ICollection<Rating> RatingsForOthers { get; set; }
 }

DTO和ViewModel calsses

public class UserInfoSummaryViewModel
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public UserDetailedStatus DetailedStatus { get; set; }
}

public class UserDetailedStatus
{
    public float TotalCredits { get; set; }
    public float Credits { get; set; }
    public float PromotionalCredits { get; set; }
    public BiddingAndItems BiddingAndItems { get; set; }
    public int OngoingListings { get; set; }
    public int NewMessages { get; set; }
    public float Rating { get; set; }
    public int NumberOfRatings { get; set; }
}

public class BiddingAndItems
{
    public int TotalBids { get; set; }
    public int WinningBids { get; set; }
    public int AcquiredItems { get; set; }
    public int ItemsAwaitingConfirmation { get; set; }
    public List<ItemForUserBids> Items { get; set; }
}

AutoMapperBootStrapper类中的映射

Mapper.CreateMap<User, BiddingAndItems>()
                .ForMember(m => m.TotalBids, o => o.MapFrom(s => s.TotalActiveBids()))
                .ForMember(m=>m.ItemsAwaitingConfirmation, o=>o.MapFrom(s=>s.Items.Count(i=>i.IsAwaitingReceptionConfirmation().Equals(true))))
                .ForMember(m=>m.AcquiredItems, o=>o.MapFrom(s=>s.AquiredItems().Count))
                .ForMember(m => m.WinningBids,
                           o => o.MapFrom(s => s.Bids.Where(c => c.Item.CurrentHighestBidderId().Equals(s.Id))));

            Mapper.CreateMap<User, UserDetailedStatus>()
                .ForMember(m => m.NumberOfRatings, o => o.MapFrom(s => s.OwnRatings.Count()))
                .ForMember(m => m.NewMessages, o => o.MapFrom(s => s.TotalUnreadMessages()))
                .ForMember(m => m.OngoingListings, o => o.MapFrom(s => s.Items.Where(i => i.IsPublished())))
                .ForMember(m => m.Rating, o => o.MapFrom(s => s.RatingAverage))
                .ForMember(m => m.TotalCredits, o => o.MapFrom(s => s.TotalCredits()));

            Mapper.CreateMap<User, UserInfoSummaryViewModel>();

调用UserController中的automapper

    public ActionResult Summary()
    {

        var user = _helper.GetUserFromSession();
        var viewModel = Mapper.Map<User, UserInfoSummaryViewModel>(user);
        return View(viewModel);
    }

我想,因为我在引导程序中有所有必要的映射,理论上工作,显然我错了......我怎么能解决这个问题?

更新

我修复了映射并添加了几个值解析器。现在我没有得到一个空引用异常,但似乎有一些错误,因为每次我运行项目时它都会卡住然后本地服务器停止响应...这是我的代码:

        Mapper.CreateMap<User, BiddingAndItems>()
            .ForMember(m => m.TotalBids, o => o.MapFrom(s => s.TotalActiveBids()))
            .ForMember(m => m.ItemsAwaitingConfirmation,
                       o => o.MapFrom(s => s.Items.Count(i => i.IsAwaitingReceptionConfirmation().Equals(true))))
            .ForMember(m => m.AcquiredItems, o => o.MapFrom(s => s.AquiredItems().Count))
            .ForMember(m => m.WinningBids, o => o.ResolveUsing<WinningBidsResolver>())
            .ForMember(m => m.Items, o => o.ResolveUsing<BiddingItemResolver>());

        Mapper.CreateMap<User, UserDetailedStatus>()
            .ForMember(m => m.NumberOfRatings, o => o.MapFrom(s => s.OwnRatings.Count()))
            .ForMember(m => m.NewMessages, o => o.MapFrom(s => s.TotalUnreadMessages()))
            .ForMember(m => m.OngoingListings, o => o.MapFrom(s => s.Items.Where(i => i.IsPublished()).Count()))
            .ForMember(m => m.Rating, o => o.MapFrom(s => s.RatingAverage))
            .ForMember(m=>m.BiddingAndItems, o => o.MapFrom(s=> s))
            .ForMember(m => m.TotalCredits, o => o.MapFrom(s => s.TotalCredits()));

        Mapper.CreateMap<User, UserInfoSummaryViewModel>()
            .ForMember(m => m.DetailedStatus, o => o.MapFrom(s => s));

public class BiddingItemResolver : ValueResolver<User, List<ItemForUserBids>>
{
    protected override List<ItemForUserBids> ResolveCore(User source)
    {
        var items = new List<ItemForUserBids>();
        foreach (var bid in source.Bids)
        {
            var item = bid.Item;
            var c = new ItemForUserBids
                        {
                            BidValue = bid.Amount,
                            Description = item.Description,
                            Id = item.Id,
                            ItemThumb = item.MainImageLink(),
                            Status = source.ItemBiddingStatus(item.Id),
                            TimeLeft = TimeUtility.TimeLeft(item.EndDate),
                            Title = item.Title
                        };
            items.Add(c);
        }
        return items;
    }
}

public class WinningBidsResolver : ValueResolver<User, int>
{
    protected override int ResolveCore(User source)
    {
        return source.Bids.Where(c => c.Item.CurrentHighestBidderId().Equals(source.Id)).Count();
    }
}

问题在于,我没有任何例外情况可以给我任何关于出错的提示......它只会被卡住!我怀疑我的映射会进入某种无限循环或类似的东西,但我不确定究竟发生了什么......有什么方法可以调试这个问题吗?

任何帮助将不胜感激......

1 个答案:

答案 0 :(得分:1)

如果没有关于您收到的异常的更多信息,我只能猜出可能出现的问题:我猜测这是因为您在MapFrom中使用了未初始化的集合上的Linq。请尝试实施ValueResolver