无法弄清楚逻辑和语法来创建此列表

时间:2015-07-02 12:10:03

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

鉴于以下edmx文件,我正在尝试编写一个异步ActionResult,它将为我提供所有用户角色未播放的场景列表。我试图找出最有效的方法,也是我的观点中获取方案列表的逻辑。我是Linq和MVC的新手,所以这一直是一个挑战。

EDMX file

我目前在ActionResult上的尝试见下文:

    // GET: Home/ChooseScenario
    public async Task<ActionResult> ChooseScenario(string charId)
    {
        //Convert passed in charId string to related Character object 
        var pFSCharacter = await db.PFSCharacters
            .FirstOrDefaultAsync(c => c.PFSCHARACTERID == charId);

        //Initialize empty list of Characters for the User 
        List<PFSCharacter> userCharacters = new List<PFSCharacter>();

        //determine if the pFSCharacter is Core and only give me back a list of characters for the user that are core as well 
        if (pFSCharacter.IsCore)
        {
            userCharacters = await db.PFSCharacters
                .Where(x => x.PFSUSERID == User.Identity.GetUserId() && x.IsCore == true)
                .ToListAsync();
        }
        //If pFSCharacter is not core give me back a list of characters for the user that are not core
        else
        {
            userCharacters = await db.PFSCharacters
                .Where(x => x.PFSUSERID == User.Identity.GetUserId() && x.IsCore == false)
                .ToListAsync();
        }

        List<PFSCharacterScenario> pFSCharacterScenarios = new List<PFSCharacterScenario>();

        //try to figure out the list of Scenarios that none of the User's characters have already participated in
        foreach (PFSCharacter character in userCharacters)
        {
            //can this be done better or in a different way that a foreach loop?
            //can't figure out the logic to give back list of scenarios that each character has not played yet

            //pFSScenarios = await db.PFSCharacterScenarios  //this will overwrite the list need to add to the 
                                                             //list already started for the other characters on 
                                                             //previous loops

            //.ToListAsync();
        }

        //need to remove duplicates scenarios from list so scenario only appears once. 

        //pair down list even further to scenarios that pFSCharacter.charLevel >= pFSScenario.minLevel 
        //and pFSCharacter.charLevel <= pFSScenario.maxLevel


        //var pFSScenarios = db.PFSScenarios
        //    .Include(p => p.PFSFirstSubmittedBy)
        //    .Include(p => p.PFSScenarioType)
        //    .Where(p => p.IsActive == true)

        //    .OrderBy(p => p.PFSSCENARIOTYPEID)
        //    .ThenBy(p => p.Season)
        //    .ThenBy(p => p.SeasonID)
        //    .ThenBy(p => p.MinLevel)
        //    .ThenBy(p => p.ScenarioName);

        //pass pFSCharacter to View to pass to next Controller ActionResult
        ViewBag.Character = pFSCharacter;

        //send list of scenarios to the View to be displayed.
        return View(await pFSScenarios);
    }
编辑:我和朋友一起制作了我需要使用的SQL查询。使用LINQ将它导入控制器的最佳方法是什么?

SELECT *
FROM PFSScenarios
Where PFSSCENARIOID NOT IN (

Select s.PFSSCENARIOID
FROM PFSScenarios s
Inner Join PFSCharacterScenarios cs
    on s.PFSSCENARIOID = cs.PFSSCENARIOID
Inner Join PFSCharacters c
    on c.PFSCHARACTERID = cs.PFSCHARACTERID
WHERE C.PFSUSERID = '35be8bbb-99dc-44bc-9d84-9bcc937d79d6'
)

EDIT3:接近,但仍然出现错误

Unable to create a constant value of type 'PFSScenarioTracker.Data.EF.PFSCharacter'. Only primitive types or enumeration types are supported in this context.

使用下面的Fabio Luz解决方案。

如果我使用空白List<PFSCharacter> userCharacters = new List<PFSCharacter>();并注释掉if/else statement填充的userCharacters,则错误消失,但是它会返回数据库中不符合我添加的其他条件的每个方案{{1 }}

这是我当前的控制器操作结果:

i => i.IsActive == true && i.MinLevel <= pFSCharacter.CharLevel && i.MaxLevel >= pFSCharacter.CharLevel &&

2 个答案:

答案 0 :(得分:1)

如果您想获得任何用户角色尚未播放的所有场景的列表:

//this returns all scenarios that have not been played by any of the Users
var scenarios = await db.PFSScenarios.Where(i => i.PFSCharacterScenarios.Any()).ToListAsync();

修改

//this returns all scenarios that have not been played by any of the User's Chars
var scenarios = await db.PFSScenarios.Where(i => !i.PFSCharacterScenarios.Any(x => userCharacters.Contains(x.PSFCharacter))).ToListAsync();

我不熟悉你的模型,不确定它是否正确。我想说的是“使用导航属性”,我认为它们将解决您的问题。

答案 1 :(得分:0)

在@Fabio的帮助下,我能够为使用此控制器的玩家正确显示列表:

    public async Task<ActionResult> ChooseScenario(string charId)
    {
        string currentUser = User.Identity.GetUserId();

        //Convert passed in charId string to related Character object 
        var pFSCharacter = await db.PFSCharacters
            .FirstOrDefaultAsync(c => c.PFSCHARACTERID == charId);

        var pFSScenarios = await db.PFSScenarios
            .Where(
                i => i.IsActive == true &&
                i.MinLevel <= pFSCharacter.CharLevel && 
                i.MaxLevel >= pFSCharacter.CharLevel &&
                !i.PFSCharacterScenarios
                .Any(
                    x => x.PFSCharacter.IsCore == pFSCharacter.IsCore &&
                    x.PFSCharacter.PFSUser.PFSUSERID == currentUser))
                .ToListAsync();

        //pass pFSCharacter to View to pass to next Controller ActionResult
        ViewBag.Character = pFSCharacter;

        //send list of scenarios to the View to be displayed.
        return View(pFSScenarios);
    }

删除了If / Else语句,并使用.any查找当前登录用户的用户ID,以查找当前PFSCharacterScenarios表中的任何字符。