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