[英]Working With Linq Query in Mapping
我有一個包含三個完美工作的方法的類:
要從表中獲取數據:
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); }
用作將列表分隔為單個元素的中間函數:
private IList<RetriveOperatorAcYo> MapToRetriveOperatorYoList(IEnumerable<EntityFramework.Person> persons) { return persons.Select(MapToRetirveOperatorYo).ToList(); }
作為生成結果的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.