繁体   English   中英

在映射中使用Linq查询

[英]Working With Linq Query in Mapping

我有一个包含三个完美工作的方法的类:

  1. 要从表中获取数据:

      public IList<RetriveOperatorAcYo> GetRetriveOperatorListGrid(int Uid) { var persons = (from p in _Context.People join a in _Context.Accounts on p.PersonId equals a.PersonId join b in _Context.BusinessTypes on a.BusinessTypeId equals b.BusinessTypeId join d in _Context.AccountUserRelations on a.AccountId equals d.AccountId where b.Name == AccountBusinessTypes.Operator && a.IsDelete == false && d.Active == true && d.UserId == Uid select p); return MapToRetriveOperatorYoList(persons); } 
  2. 用作将列表分隔为单个元素的中间函数:

      private IList<RetriveOperatorAcYo> MapToRetriveOperatorYoList(IEnumerable<EntityFramework.Person> persons) { return persons.Select(MapToRetirveOperatorYo).ToList(); } 
  3. 作为生成结果的Mapping函数:

      private RetriveOperatorAcYo MapToRetirveOperatorYo(EntityFramework.Person person) { var vendorYo = new RetriveOperatorAcYo { Id = person.PersonId, FirstName = person.FirstName, LastName = person.LastName, MobileNumber = person.MobileNumber, LandlineNumber = person.LandlineNumber } return vendorYo; } 

现在,我只想在第一个函数中获取特定的列数据。

我搜索了一些技巧并尝试了以下方法:

var persons = (from p in _Context.People
               join a in _Context.Accounts on p.PersonId equals a.PersonId
               join b in _Context.BusinessTypes on a.BusinessTypeId equals b.BusinessTypeId
               join d in _Context.AccountUserRelations on a.AccountId equals d.AccountId
               where b.Name == AccountBusinessTypes.Operator && a.IsDelete == false && d.Active == true && d.UserId == Uid
               select new 
               {
                  PersonId = p.PersonId,
                  FirstName = p.FirstName,
                  LastName = p.LastName,
                  MobileNumber = p.MobileNumber,
                  LandlineNumber = p.LandlineNumber
               });

但这给了我第二个功能的错误

“不能在LINQ to Entities查询中构造实体或复杂类型。”

那么有什么解决方案如何映射数据并仅返回具有特定详细信息的特定映射类。

我在这里先向您的帮助表示感谢。

您尚未指定应使用LINQ查询创建哪个类。 尝试

var persons = (from p in _Context.People
           join a in _Context.Accounts on p.PersonId equals a.PersonId
           join b in _Context.BusinessTypes on a.BusinessTypeId equals b.BusinessTypeId
           join d in _Context.AccountUserRelations on a.AccountId equals d.AccountId
           where b.Name == AccountBusinessTypes.Operator && a.IsDelete == false && d.Active == true && d.UserId == Uid
           select new RetriveOperatorAcYo()
           {
              PersonId = p.PersonId,
              FirstName = p.FirstName,
              LastName = p.LastName,
              MobileNumber = p.MobileNumber,
              LandlineNumber = p.LandlineNumber
           });

要使用3种方法维护模式并进行所需的部分查询,而在第一种方法中不使用现有的DTO,则必须诉诸于传递动态对象并更改方法签名。 尽管不建议这样做,但类似的事情应该可以工作-请注意在第二种和第三种方法中使用dynamic

public IList<RetriveOperatorAcYo> GetRetriveOperatorListGrid(int Uid)
{
    var persons = (from p in _Context.People
        join a in _Context.Accounts on p.PersonId equals a.PersonId
        join b in _Context.BusinessTypes on a.BusinessTypeId equals b.BusinessTypeId
        join d in _Context.AccountUserRelations on a.AccountId equals d.AccountId
        where b.Name == AccountBusinessTypes.Operator && a.IsDelete == false && d.Active == true && d.UserId == Uid
        select new 
        {
            PersonId = p.PersonId,
            FirstName = p.FirstName,
            LastName = p.LastName,
            MobileNumber = p.MobileNumber,
            LandlineNumber = p.LandlineNumber
         });
    return MapToRetirveOperatorYo(persons);
}

private IList<RetriveOperatorAcYo> MapToRetriveOperatorYoList(IEnumerable<dynamic> persons)
{
    return persons.Select(MapToRetirveOperatorYo).ToList();
}

private RetriveOperatorAcYo MapToRetirveOperatorYo(dynamic person)
{
    var vendorYo = new RetriveOperatorAcYo
    {
        Id = person.PersonId,
        FirstName = person.FirstName,
        LastName = person.LastName,
        MobileNumber = person.MobileNumber,
        LandlineNumber = person.LandlineNumber
    }
    return vendorYo;

}

本答案所述,更好的选择是更改您的第一种方法以select new RetriveOperatorAcYo

这种方法的问题在于,EF无法部分加载带有选定列的EF类型。 如果使用部分信息加载类型,则它不知道如何处理其余未填充的列。 更新中应该做什么? 为了使用这些局部列,您可以创建另一个类来为您保存此信息。 但是即使如此,您仍必须决定如何处理MapToRetirveOperatorYo方法中未选择的列。 这里是演示:

public class PersonDTO
        {
            public long PersonID { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string MobileNumber { get; set; }
            public string LandlineNumber { get; set; }
        }

现在,当您要创建匿名类时可以使用此类:

var persons = (from p in _Context.People
                join a in _Context.Accounts on p.PersonId equals a.PersonId
                join b in _Context.BusinessTypes on a.BusinessTypeId equals b.BusinessTypeId
                join d in _Context.AccountUserRelations on a.AccountId equals d.AccountId
                where b.Name == AccountBusinessTypes.Operator && a.IsDelete == false && d.Active == true && d.UserId == Uid
                select new PersonDTO()
                {
                    PersonId = p.PersonId,
                    FirstName = p.FirstName,
                    LastName = p.LastName,
                    MobileNumber = p.MobileNumber,
                    LandlineNumber = p.LandlineNumber
                }); 

在您的其他功能中:

private IList<RetriveOperatorAcYo> MapToRetriveOperatorYoList(IEnumerable<PersonDTO> persons)
{
        //here you have to decide what to do with Email, DOB and active as 
        //you are not selecting those in your Person DTO class ! Here is where EF would not know what to do.
        return person.Select(person => new RetriveOperatorAcYo
        {
            Id = person.PersonId,
            FirstName = person.FirstName,
            LastName = person.LastName,
            MobileNumber = person.MobileNumber,
            LandlineNumber = person.LandlineNumber,
            Email = person.Email, //Error
            DOB = person.DOB, //Error
            Active = person.Active //Error
        }.ToList()
 }

阅读了所有讨论和好的建议之后,我想您的答案是, ,没有任何解决方案可以映射数据并仅返回具有特定详细信息的特定映射类。 我认为您将必须致电Microsoft并说服他们更改EF应如何接受部分对象。 这是正确的答案,因为您不想更改现有代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM