Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 查询中的多个联接_Asp.net Mvc_Entity Framework - Fatal编程技术网

Asp.net mvc 查询中的多个联接

Asp.net mvc 查询中的多个联接,asp.net-mvc,entity-framework,Asp.net Mvc,Entity Framework,早些时候,我在向查询添加联接方面得到了一些帮助。我现在意识到我实际上需要在同一个查询中添加多个连接,但我尝试了许多方法(基于原始连接),但不断出现错误 我有一个叫做SchemeName的模型- namespace TRS.Models { public class SchemeName { [Key] public int SchemeNameID { get; set; } [Display(Name = "Scheme Name

早些时候,我在向查询添加联接方面得到了一些帮助。我现在意识到我实际上需要在同一个查询中添加多个连接,但我尝试了许多方法(基于原始连接),但不断出现错误

我有一个叫做SchemeName的模型-

namespace TRS.Models
{
    public class SchemeName
    {
        [Key]
        public int SchemeNameID { get; set; }
        [Display(Name = "Scheme Name")]
        public string Name { get; set; }

        public virtual ICollection<Benefit> Benefits { get; set; }
    }
}
在我的控制器中,我有以下内容:

var trs = db.Users
                .Join(db.SchemeNames,
                user => user.Pension.PensionSchemeNameID, 
                schemeName => schemeName.SchemeNameID,
                (user, schemeName) => new { User = user, SchemeName = schemeName })
                .Where(a => UserIDs.Contains(a.User.UserName))
                .Select(a => new TRSViewModel
            { 
                UserName = a.User.UserName,
                FirstName = a.User.UserDetails.FirstName,
                LastName = a.User.UserDetails.LastName,
                Salary = a.User.UserDetails.Salary,
                PensionSchemeName = a.SchemeName.Name,
这对于显示PensionSchemeName非常有用,但我也需要显示LifeAssuranceSchemeName(以及其他),但正如我提到的,不断出现错误。我想我只需要添加一个附加的连接,包含LifeAssuranceSchemeName的详细信息,所以我尝试添加-

                var trs = db.Users
                .Join(db.SchemeNames,
                user => user.Pension.PensionSchemeNameID, 
                schemeName => schemeName.SchemeNameID,
                (user, schemeName) => new { User = user, SchemeName = schemeName })
                .Join(db.SchemeNames,
                la => la.Pension.PensionSchemeNameID,
                schemeName => schemeName.SchemeNameID,
                (user, schemeName) => new { User = user, SchemeName = schemeName })
                .Where(a => UserIDs.Contains(a.User.UserName))
                .Select(a => new TRSViewModel
但这给了我一个错误-

错误10“AnonymousType#1”不包含“Pension”的定义,并且找不到接受“AnonymousType#1”类型的第一个参数的扩展方法“Pension”(是否缺少using指令或程序集引用?)


知道如何添加这些附加联接吗?

我认为这些联接没有正确链接

在第二个联接中,第二个参数引用外部集合。这将是从第一个join
new{User=User,SchemeName=SchemeName})
中投影的匿名类型

假设User类上有一个属性生命保证,那么我猜您希望基于User对象中的该属性进行第二次连接,如下所示:

var trs = db.Users
            .Join(db.SchemeNames,
                 user => user.Pension.PensionSchemeNameID, 
                 schemeName => schemeName.SchemeNameID,
                 (user, schemeName) => new { User = user, 
                                             SchemeName = schemeName })
            .Join(db.SchemeNames,
                 x => x.User.LifeAssurance.LifeAssuranceSchemeNameID,
                 schemeName => schemeName.SchemeNameID,
                 (x, schemeName) => new { User = x.User, 
                                          PensionSchemeName = x.SchemeName, 
                                          LifeAssuranceSchemeName = schemeName })
            .Where(a => UserIDs.Contains(a.User.UserName))
            .Select(a => new TRSViewModel{
                          UserName = a.User.UserName,
                          FirstName = a.User.UserDetails.FirstName,
                          LastName = a.User.UserDetails.LastName,
                          Salary = a.User.UserDetails.Salary,
                          PensionSchemeName = a.PensionSchemeName.Name,
                          LifeAssuranceSchemeName = a.LifeAssuranceSchemeName.Name
            });
这可以写在查询语法上(可能更容易阅读):

最后,考虑到这些是内部连接,因此任何没有养老金或人寿保险方案的用户都不会被返回。如果您想要左联接,可以执行类似于所描述的方法的操作(尽管我想您不需要这样做,否则
user.Pension.PensionSchemeNameID
之类的表达式将在有没有Pension的用户时抛出NullReferenceException)

我已经使用内存集合中的以下代码快速测试了这些查询,但它们应该正确地转换为实体框架的SQL:

public class SchemeName
{
    public int SchemeNameID { get; set; }
    public string Name { get; set; }
}

public class Pension
{
    public int PensionSchemeNameID { get; set; }
}

public class LifeAssurance
{
    public int LifeAssuranceSchemeNameID { get; set; }
}

public class User
{
    public string Name { get; set; }
    public Pension Pension { get; set; }
    public LifeAssurance LifeAssurance { get; set; }
}

public static class db
{
    public static IEnumerable<User> Users = new List<User>() { 
            new User { Name = "User 1", 
                        Pension = new Pension { PensionSchemeNameID = 1 }, 
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = 2 } },
            new User { Name = "User 2", 
                        Pension = new Pension { PensionSchemeNameID = 1 }, 
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = 2 } },
            new User { Name = "User 3", 
                        Pension = new Pension { PensionSchemeNameID = 1 },
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = -999 }},
            new User { Name = "User 4", 
                        Pension = new Pension { PensionSchemeNameID = -999 }, 
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = 2 } }
    };
    public static IEnumerable<SchemeName> SchemeNames = new List<SchemeName>() { 
                new SchemeName{ SchemeNameID = 1, Name = "Scheme 1"  },
                new SchemeName{ SchemeNameID = 2, Name = "Scheme 2"  }
    };
}

    private void Run()
    {
        var innerJoinQuery1 = db.Users
                    .Join(db.SchemeNames,
                            user => user.Pension.PensionSchemeNameID,
                            schemeName => schemeName.SchemeNameID,
                            (user, schemeName) => new
                            {
                                User = user,
                                SchemeName = schemeName
                            })
                    .Join(db.SchemeNames,
                            x => x.User.LifeAssurance.LifeAssuranceSchemeNameID,
                            schemeName => schemeName.SchemeNameID,
                            (x, schemeName) => new
                            {
                                User = x.User,
                                PensionSchemeName = x.SchemeName,
                                LifeAssuranceSchemeName = schemeName
                            })
                    .Where(a => a.User.Name.StartsWith("User "))
                    .Select(a => new 
                    {
                        UserName = a.User.Name,
                        PensionSchemeName = a.PensionSchemeName.Name,
                        LifeAssuranceSchemeName = a.LifeAssuranceSchemeName.Name
                    });

        var innerJoinQuery2 = from user in db.Users
                     join pensionSchema in db.SchemeNames
                        on user.Pension.PensionSchemeNameID equals pensionSchema.SchemeNameID
                     join lifeAssuranceSchema in db.SchemeNames
                        on user.LifeAssurance.LifeAssuranceSchemeNameID equals lifeAssuranceSchema.SchemeNameID
                     where user.Name.StartsWith("User ")
                     select new
                               {
                                   UserName = user.Name,
                                   PensionSchemeName = pensionSchema.Name,
                                   LifeAssuranceSchemeName = lifeAssuranceSchema.Name
                               };

        var lefJoinQuery =
                      from user in db.Users
                      from pensionScheme in db.SchemeNames
                              .Where(s => s.SchemeNameID == user.Pension.PensionSchemeNameID)
                              .DefaultIfEmpty()
                      from lifeAssuranceScheme in db.SchemeNames
                              .Where(s => s.SchemeNameID == user.LifeAssurance.LifeAssuranceSchemeNameID)
                              .DefaultIfEmpty()
                      select new
                      {
                          UserName = user.Name,
                          PensionSchemeName = pensionScheme != null ? pensionScheme.Name : "No Pension",
                          LifeAssuranceSchemeName = lifeAssuranceScheme != null ? lifeAssuranceScheme.Name : "No Life Assurance"
                      }; 

        foreach (var result in innerJoinQuery1)
            Print(result.UserName, result.PensionSchemeName, result.LifeAssuranceSchemeName);

        Console.WriteLine();

        foreach (var result in innerJoinQuery2)
            Print(result.UserName, result.PensionSchemeName, result.LifeAssuranceSchemeName);

        Console.WriteLine();

        foreach (var result in lefJoinQuery)
            Print(result.UserName, result.PensionSchemeName, result.LifeAssuranceSchemeName);

        Console.WriteLine();

        Console.ReadKey();
    }

    private void Print(string user, string pension, string lifeAssurance)
    {
        Console.WriteLine(String.Format("User: '{0}', Pension: '{1}', Life Assurance: '{2}'", user, pension, lifeAssurance));
    }
}
公共类SchemeName
{
公共int SchemeNameID{get;set;}
公共字符串名称{get;set;}
}
公营养老金
{
public int pensionschemenaid{get;set;}
}
公共舱人寿保险
{
公共int-LifeAssuranceSchemeNameID{get;set;}
}
公共类用户
{
公共字符串名称{get;set;}
公共养老金{get;set;}
公共人寿保险人寿保险{get;set;}
}
公共静态类数据库
{
public static IEnumerable Users=新列表(){
新用户{Name=“用户1”,
养老金=新养老金{PensionSchemeNameID=1},
人寿保险=新人寿保险{LifeAssuranceSchemeNameID=2},
新用户{Name=“用户2”,
养老金=新养老金{PensionSchemeNameID=1},
人寿保险=新人寿保险{LifeAssuranceSchemeNameID=2},
新用户{Name=“User 3”,
养老金=新养老金{PensionSchemeNameID=1},
人寿保险=新人寿保险{LifeAssuranceSchemeNameID=-999},
新用户{Name=“User 4”,
养老金=新养老金{PensionSchemeNameID=-999},
人寿保险=新人寿保险{LifeAssuranceSchemeNameID=2}
};
公共静态IEnumerable SchemeNames=new List(){
新SchemeName{SchemeNameID=1,Name=“Scheme 1”},
新SchemeName{SchemeNameID=2,Name=“Scheme 2”}
};
}
私家车
{
var innerJoinQuery1=db.Users
.Join(db.SchemeNames,
user=>user.Pension.PensionSchemeNameID,
schemeName=>schemeName.SchemeNameID,
(用户,schemeName)=>新建
{
用户=用户,
SchemeName=SchemeName
})
.Join(db.SchemeNames,
x=>x.User.LifeAssurance.LifeAssuranceSchemeNameID,
schemeName=>schemeName.SchemeNameID,
(x,schemeName)=>新建
{
User=x.User,
PensionSchemeName=x.SchemeName,
LifeAssuranceSchemeName=schemeName
})
.Where(a=>a.User.Name.StartsWith(“用户”))
.选择(a=>新建
{
用户名=a.User.Name,
PensionSchemeName=a.PensionSchemeName.Name,
LifeAssuranceSchemeName=a.LifeAssuranceSchemeName.Name
});
var innerJoinQuery2=来自db.Users中的用户
在db.SchemeNames中加入pensionSchema
在user.Pension.PensionSchemeNameID上等于pensionSchema.SchemeNameID
在db.SchemeNames中加入lifeAssuranceSchema
在user.LifeAssurance.LifeAssuranceSchemeNameID上等于lifeAssuranceSchema.SchemeNameID
其中user.Name.StartsWith(“用户”)
选择新的
{
用户名=user.Name,
PensionSchemeName=pensionSchema.Name,
LifeAssuranceSchemeName=lifeAssuranceSchema.Name
};
var-lefJoinQuery=
来自db.Users中的用户
来自db.SchemeNames中的pensionScheme
.Where(s=>s.SchemeNameID==user.Pension.PensionSchemeNameID)
.DefaultIfEmpty()
来自db.SchemeNames中的lifeAssuranceScheme
var trs = from user in db.Users
          join pensionSchema in db.SchemeNames 
               on user.Pension.PensionSchemeNameID equals pensionSchema.SchemeNameID
          join lifeAssuranceSchema in db.SchemeNames 
               on user.LifeAssurance.LifeAssuranceSchemeNameID equals lifeAssuranceSchema.SchemeNameID
          where UserIds.Contains(user.UserName)
          select new TRSViewModel{
                      UserName = user.UserName,
                      FirstName = user.UserDetails.FirstName,
                      LastName = user.UserDetails.LastName,
                      Salary = user.UserDetails.Salary,
                      PensionSchemeName = pensionSchema.Name,
                      LifeAssuranceSchemeName = lifeAssuranceSchema.Name }
var query =
      from user in db.Users
      from pensionScheme in db.SchemeNames
              .Where(s => s.SchemeNameID == user.Pension.PensionSchemeNameID)
              .DefaultIfEmpty()
      from lifeAssuranceScheme in db.SchemeNames
              .Where(s => s.SchemeNameID == user.LifeAssurance.LifeAssuranceSchemeNameID)
              .DefaultIfEmpty()
      select new { User = user, 
                   Pension = pensionScheme, 
                   LifeAssurance = lifeAssuranceScheme} 
public class SchemeName
{
    public int SchemeNameID { get; set; }
    public string Name { get; set; }
}

public class Pension
{
    public int PensionSchemeNameID { get; set; }
}

public class LifeAssurance
{
    public int LifeAssuranceSchemeNameID { get; set; }
}

public class User
{
    public string Name { get; set; }
    public Pension Pension { get; set; }
    public LifeAssurance LifeAssurance { get; set; }
}

public static class db
{
    public static IEnumerable<User> Users = new List<User>() { 
            new User { Name = "User 1", 
                        Pension = new Pension { PensionSchemeNameID = 1 }, 
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = 2 } },
            new User { Name = "User 2", 
                        Pension = new Pension { PensionSchemeNameID = 1 }, 
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = 2 } },
            new User { Name = "User 3", 
                        Pension = new Pension { PensionSchemeNameID = 1 },
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = -999 }},
            new User { Name = "User 4", 
                        Pension = new Pension { PensionSchemeNameID = -999 }, 
                        LifeAssurance = new LifeAssurance { LifeAssuranceSchemeNameID = 2 } }
    };
    public static IEnumerable<SchemeName> SchemeNames = new List<SchemeName>() { 
                new SchemeName{ SchemeNameID = 1, Name = "Scheme 1"  },
                new SchemeName{ SchemeNameID = 2, Name = "Scheme 2"  }
    };
}

    private void Run()
    {
        var innerJoinQuery1 = db.Users
                    .Join(db.SchemeNames,
                            user => user.Pension.PensionSchemeNameID,
                            schemeName => schemeName.SchemeNameID,
                            (user, schemeName) => new
                            {
                                User = user,
                                SchemeName = schemeName
                            })
                    .Join(db.SchemeNames,
                            x => x.User.LifeAssurance.LifeAssuranceSchemeNameID,
                            schemeName => schemeName.SchemeNameID,
                            (x, schemeName) => new
                            {
                                User = x.User,
                                PensionSchemeName = x.SchemeName,
                                LifeAssuranceSchemeName = schemeName
                            })
                    .Where(a => a.User.Name.StartsWith("User "))
                    .Select(a => new 
                    {
                        UserName = a.User.Name,
                        PensionSchemeName = a.PensionSchemeName.Name,
                        LifeAssuranceSchemeName = a.LifeAssuranceSchemeName.Name
                    });

        var innerJoinQuery2 = from user in db.Users
                     join pensionSchema in db.SchemeNames
                        on user.Pension.PensionSchemeNameID equals pensionSchema.SchemeNameID
                     join lifeAssuranceSchema in db.SchemeNames
                        on user.LifeAssurance.LifeAssuranceSchemeNameID equals lifeAssuranceSchema.SchemeNameID
                     where user.Name.StartsWith("User ")
                     select new
                               {
                                   UserName = user.Name,
                                   PensionSchemeName = pensionSchema.Name,
                                   LifeAssuranceSchemeName = lifeAssuranceSchema.Name
                               };

        var lefJoinQuery =
                      from user in db.Users
                      from pensionScheme in db.SchemeNames
                              .Where(s => s.SchemeNameID == user.Pension.PensionSchemeNameID)
                              .DefaultIfEmpty()
                      from lifeAssuranceScheme in db.SchemeNames
                              .Where(s => s.SchemeNameID == user.LifeAssurance.LifeAssuranceSchemeNameID)
                              .DefaultIfEmpty()
                      select new
                      {
                          UserName = user.Name,
                          PensionSchemeName = pensionScheme != null ? pensionScheme.Name : "No Pension",
                          LifeAssuranceSchemeName = lifeAssuranceScheme != null ? lifeAssuranceScheme.Name : "No Life Assurance"
                      }; 

        foreach (var result in innerJoinQuery1)
            Print(result.UserName, result.PensionSchemeName, result.LifeAssuranceSchemeName);

        Console.WriteLine();

        foreach (var result in innerJoinQuery2)
            Print(result.UserName, result.PensionSchemeName, result.LifeAssuranceSchemeName);

        Console.WriteLine();

        foreach (var result in lefJoinQuery)
            Print(result.UserName, result.PensionSchemeName, result.LifeAssuranceSchemeName);

        Console.WriteLine();

        Console.ReadKey();
    }

    private void Print(string user, string pension, string lifeAssurance)
    {
        Console.WriteLine(String.Format("User: '{0}', Pension: '{1}', Life Assurance: '{2}'", user, pension, lifeAssurance));
    }
}