C# 如何基于另一个表的ID获取一个表的数据

C# 如何基于另一个表的ID获取一个表的数据,c#,entity-framework,linq,relationship,C#,Entity Framework,Linq,Relationship,我已经创建了3个关系表(用户、项目、产品) 一个用户有多个项目,一个项目有多个产品(一对多) 我需要在用户登录时显示所有项目和包含的产品 我已经用下面的代码完成了,但我不认为这是最好的处理方法。我需要做得更好 public ActionResult Index() { ModulesViewModel mvm = new ModulesViewModel(); List<Modules> modules = new List<Modul

我已经创建了3个关系表(用户、项目、产品)

一个用户有多个项目,一个项目有多个产品(一对多)

我需要在用户登录时显示所有项目和包含的产品

我已经用下面的代码完成了,但我不认为这是最好的处理方法。我需要做得更好

public ActionResult Index()
    {

        ModulesViewModel mvm = new ModulesViewModel();
        List<Modules> modules = new List<Modules>();
        var userId = User.Identity.GetUserId();
        var projects = _adsDbContext.Project.Where(x=>x.UserID == userId).ToList();
        foreach (var pro in projects)
        {

            var productData = _adsDbContext.Product.Where(x => x.ProjectID == pro.ProjectID); 
            modules.AddRange(productData);

        }
        modules = modules.OrderBy(x => x.ProjectID).OrderBy(x=>x.ModuleNumber).ToList();
        mvm.Modules = modules;
        return View(mvm);
    }

public class Project
{
    public int ProjectID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<ProductData> Products { get; set; }


    public string UserID { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class ProductData : Modules
{
    public int ProductDataID { get; set; }
    public float ConversionRate { get; set; }
    public float Price { get; set; }
    public float TotalSales { get; set; }
    public float GrossSales { get; set; }
    public float NetProfit { get; set; }
    public float ProfitPerLead { get; set; }
}


public abstract class Modules
{

    public int ProjectID { get; set; }
    public virtual Project Project { get; set; }
}
public ActionResult Index()
{
ModulesViewModel mvm=新的ModulesViewModel();
列表模块=新列表();
var userId=User.Identity.GetUserId();
var projects=_adsDbContext.Project.Where(x=>x.UserID==UserID.ToList();
foreach(项目中的var pro)
{
var productData=_adsDbContext.Product.Where(x=>x.ProjectID==pro.ProjectID);
modules.AddRange(productData);
}
modules=modules.OrderBy(x=>x.projectd).OrderBy(x=>x.ModuleNumber.ToList();
mvm.模块=模块;
返回视图(mvm);
}
公共类项目
{
公共int ProjectID{get;set;}
公共字符串名称{get;set;}
公共虚拟ICollection产品{get;set;}
公共字符串用户标识{get;set;}
公共虚拟应用程序用户应用程序用户{get;set;}
}
公共类ProductData:模块
{
public int ProductDataID{get;set;}
公共浮点转换率{get;set;}
公开浮动价格{get;set;}
公共浮点TotalSales{get;set;}
公共浮点Grossales{get;set;}
公共浮动净利润{get;set;}
公共浮点ProfitPerLead{get;set;}
}
公共抽象类模块
{
公共int ProjectID{get;set;}
公共虚拟项目{get;set;}
}

这很好,但我需要以更好的方式来做,而不是从头开始创建关系或使查询更好。

您的模型包含项目每一端的导航属性,以生成一对多关系

这允许您从项目启动查询,应用过滤器,然后使用集合导航属性向下“导航”,然后选择Many:

var modules = _adsDbContext.Project
    .Where(x => x.UserID == userId)
    .SelectMany(x => x.Products) // <--
    .OrderBy(x => x.ProjectID).ThenBy(x => x.ModuleNumber)
    .ToList<Modules>();
var modules=\u adsDbContext.Project
.Where(x=>x.UserID==UserID)
.SelectMany(x=>x.Products)//x.ProjectID)。然后按(x=>x.ModuleNumber)
.ToList();
或者,您可以从产品启动查询,并使用引用导航属性向上“导航”以应用过滤器:

var modules = _adsDbContext.Product
    .Where(x => x.Project.UserID == userId) // <--
    .OrderBy(x => x.ProjectID).ThenBy(x => x.ModuleNumber)
    .ToList<Modules>();
var modules=\u adsDbContext.Product
.Where(x=>x.Project.UserID==UserID)//x.ProjectID).ThenBy(x=>x.ModuleNumber)
.ToList();

感谢您的回复,我遇到的另一个问题是:我使用模块作为product和其他类型的基类,因此我逐个获取所有不同的模块,并将其添加到模块列表中,然后在前端迭代模块,需要显式转换到child,然后显示详细信息,我能做得更好吗?我还需要立即保存项目和产品,如果项目没有创建,如果项目已经创建,那么只更新产品。恐怕我们不能在一篇文章中涵盖多个问题。以上答案是基于您文章中的用例和代码。如果您有其他问题/用例,创建单独的问题,并清楚地解释它们以及目标。