簡體   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