1

私は MVC、リポジトリ パターン、および EF を学んでおり、複数のエンティティをクエリするクエリを含むメソッドをリポジトリに統合する最善の方法についてアドバイスが必要です。

現時点では、インターフェイスを実装し、DbContext のインスタンスを使用して Entity Framework を使用してデータベースからデータを取得するリポジトリ クラスを作成しましたが、エンティティは 1 つです。

編集済み...リポジトリに GetJourneys() メソッドがありますが、コントローラーのクエリからジャーニーの詳細を取得する方法がわかりません。ユーザーの詳細を取得できます。

public IEnumerable<User> GetJourneys()
    {
        var todayDate = DateTime.Now;

        //Woking with many to many Relationship 
        //(join tables) in Asp.net MVC/Entity Framework
        var viewModel = from j in dbContext.Users
                        from u in dbContext.Journeys
                        where u.DepartDate >= todayDate.Date
                        orderby u.DepartDate ascending
                        select j;

        return viewModel.ToList();
    }

以下は私の User エンティティです

public class User
{
    [Key, Required]
    public int UserID { get; set; }

    [MaxLength(30), Required]
    public string FirstName { get; set; }

    [MaxLength(30), Required]
    public string LastName { get; set; }

    [Required]
    public string ProfileImg { get; set; }

    [MaxLength(30), Required]
    public string FbLink { get; set; }

    public ICollection<Journey> Journeys { get; set; }
}

以下は私のコントローラーです

public ViewResult Search()
    {
        var userJourneyList = from user in repository.GetJourneys() select user;
        var searchView = new List<SearchViewModel>();
        try
        {
            if (userJourneyList.Any())
            {
                foreach (var user in userJourneyList)
                {
                    searchView.Add(new SearchViewModel()
                    {
                        //JourneyDestination = user.Journeys.FromDestination,
                        //JourneyDate = user.Journeys.DepartDate,
                        UserName = user.FirstName,
                        ProfileImage = user.ProfileImg,
                        //SeatsAvailable = user.Journeys.SeatsAvailable,
                        //UserType = user.Journeys.UserType
                    });
                }
                returnAmount = 1;
                ViewBag.Amount = returnAmount;
            }
            else
            {
                returnAmount = 0;
                ViewBag.Amount = returnAmount;
            }
            var todayDate = DateTime.Now;
        }
        catch (NullReferenceException ex)
        {
            MessageBox.Show(ex.Message);
        }

        return View(searchView.ToList());
    }

UPDATE今私のリポジトリで

public IList<User> GetAllUsersWithJourneys()
    {
        using (var db = new EfDbContext())
        {
            var users = from userJourney in db.Users.Include(i => i.Journeys)
                        select userJourney;
            return users.ToList();
        }
    } 

ただし、旅の詳細を取得する方法はまだわかりません。My User エンティティと Journey エンティティは、多対多の関係に関して正しいです。以下は、新しいリポジトリ メソッドを使用したコントローラーです。

        var userJourney = repository.GetAllUsersWithJourneys();
        var searchView = new List<SearchViewModel>();
        try
        {
            if (userJourneyList.Any())
            {
                foreach (var user in userJourney)
                {
                    searchView.Add(new SearchViewModel()
                        {
                            UserName = user.FirstName,
                            JourneyDestination = user.Journeys.ToDestination //ERROR
                        });
                }
            }
            else
            {
                //user will be notified that no results were found and that they are given the option to create the journey that they seek
                returnAmount = 0;
                ViewBag.Amount = returnAmount;
            }
        }
        catch (NullReferenceException ex)
        {
            MessageBox.Show(ex.Message);
        }

        return View(searchView.ToList());

私のViewModelは次のようになります

public class SearchViewModel
{
    public string ProfileImage { get; set; } //User
    public string JourneyDestination { get; set; } //Journey
    public DateTime JourneyDate { get; set; } //Journey
    public string UserName { get; set; } //User
    public int SeatsAvailable { get; set; } //Journey
    public bool UserType { get; set; } //Journey
}
4

2 に答える 2

2

あなたがしようとしているのが、すべてのユーザー ジャーニーを 1 つのリストにフラット化することである場合 (ビューに渡すモデルの形状に基づく仮定)、それを行う 1 つの方法は次のようになります。

var userJourney = repository.GetAllUsersWithJourneys();
var searchView = new List<SearchViewModel>();
try
{   
    if (userJourneyList.Any())
    {
        foreach (var user in userJourney)
        {
            foreach(var journey in user.Journeys)
            {
                searchView.Add(new SearchViewModel()
                    {
                        UserName = user.FirstName,
                        JourneyDestination = journey.JourneyDestination
                    });                
            }
        }
    }
}
 catch (NullReferenceException ex)
 {
     // ... 
 }

または、より機能的になるようにリファクタリングすることもできます。

var userJourney = repository.GetAllUsersWithJourneys();
var searchView = userJourney.SelectMany(
    user => user.Journeys.Select(
        journey => new SearchViewModel()
            {
                UserName = user.FirstName,
                JourneyDestination = journey.JourneyDestination
            }
        )
    )
    .ToList();        

if (!searchView.Any())
{
    // no results logic
}

IQueryable<User>2 番目の方法は、リポジトリがを呼び出しToList()て返すのIList<User>ではなく返された場合にさらに優れていますが、すぐに破棄するリポジトリでは機能しません。DbContext現状では ( を使用してToList())、SQL に作業を任せた場合よりも多くの処理をメモリ内で実行することになります。リポジトリが について知っていればSearchViewModel、次のようにすることができます。

public IList<SearchViewModel> GetSearchViewModels()
{
    using (var db = new EfDbContext())
    {
        var users = from user in db.Users
                    from journey in user.Journeys
                    select new SearchViewModel()
                    {
                        UserName = user.FirstName,
                        JourneyDestination = journey.JourneyDestination
                     }
                    select userJourney;

        return users.ToList();
    }
} 

ただし、アーキテクチャの厳密さによっては、プレゼンテーション レイヤーとデータ レイヤーの混在が許容できない場合があります。

于 2013-08-25T14:05:52.257 に答える