2017-02-22 2 views
1

아래 코드 스 니펫과 같이 두 개의 파생 클래스가있는 인터페이스를 만들었으므로이 파생 클래스의 멤버에 Linq 쿼리에 액세스하고 싶습니다.하지만이를 수행 할 수 없습니다.Linq 쿼리의 인터페이스에서 파생 클래스의 액세스 속성?

모델 클래스 구조 :

아래
List<IDirDetails> data = LoadData();     
int totalRecords = data.Count; 

if (!string.IsNullOrEmpty(search) && !string.IsNullOrWhiteSpace(search)) 
{ 
    // Apply search 
    data = data.Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || //not allowing to access FileName 
          p.FileSize.ToLower().Contains(search.ToLower()) ||    //not allowing to access FileSize 
          p.FileModified.ToString().ToLower().Contains(search.ToLower())).ToList(); //not allowing to accessFileModified 
} 

내가 LoadData()

public List<IDirDetails> LoadData() 
{ 
    string userName = HttpContext.User.Identity.Name; 
    var user = _context.Users.FirstOrDefault(m => m.UserName == userName);   
    string[] appList = null; 
    var allDirDetails = new List<IDirDetails>(); //obj of an Interface 
    var allAppExist = _context.UserApplications.Any(ua => ua.AppId == 17 && ua.UserId == user.Id); 

    appList = (from a in _context.Applications 
       join ua in _context.UserApplications on a.Id equals ua.AppId 
       where ua.UserId == user.Id 
       select a.AppName).ToArray(); 

    DirectoryDetails dirDetails = new DirectoryDetails(); 
    dirDetails.ApplicationList = appList; 

    List<DirectoryItemInfo> dirItems = new List<DirectoryItemInfo>(); 
    dirDetails.Items = dirItems; 

    allDirDetails.Add(dirDetails); // adding values into DirectoryDetails 

    string requestPath = Request.Path.Value; 

    string[] requestPathParts = requestPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries); 
    dirDetails.PathElements = requestPathParts; 

    var aapId = _context.Applications.FirstOrDefault(a => a.AppName == requestPathParts[0].ToString()); 

    string[] physicalPaths = (from ap in _context.ApplicationPathElements 
           join a in _context.Applications on ap.AppId equals a.Id 
           where a.Id == aapId.Id 
           select ap.AppPathElement).ToArray(); 
    if (physicalPaths != null && physicalPaths.Length > 0) 
    { 
     foreach (string indexPath in physicalPaths) 
     { 
      DirectoryItemInfo details = GetDirectoryInfo(indexPath, indexPath + "/", DateTime.MinValue);   
      allDirDetails.Add(details); // adding values into DirectoryItemInfo 
     } 
    }    
    return allDirDetails; 
} 
에 해당 클래스의 값을 설정하고있어 어떻게 : 그 멤버에 액세스하려고

public interface IDirDetails 
{ 
} 
public class DirectoryDetails: IDirDetails 
{ 
    public string[] PathElements { get; set; } 
    public string[] ApplicationList { get; set; } 

    public List<DirectoryItemInfo> Items { get; set; } 
} 
public class DirectoryItemInfo: IDirDetails 
{ 
    public string FileName { get; set; } 
    public string FileType { get; set; } 
    public string FileSize { get; set; } 
    public string FileIcon { get; set; } 
    public DateTime FileModified { get; set; } 
    public string FilePath { get; set; } 
} 

코드 양식

누군가가 deri의 필수 구성원에 어떻게 액세스해야하는지 제안 해주십시오. 인터페이스의 ved 클래스? 귀하의 질문에

답변

1

간단한 대답은 : 그냥

data = data.Cast<DirectoryItemInfo>().Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
         p.FileSize.ToLower().Contains(search.ToLower()) ||    
         p.FileModified.ToString().ToLower().Contains(search.ToLower())).ToList(); 

캐스트 또는 오른쪽 대답은입니다 OfType

data = data.OfType<DirectoryItemInfo>().Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
         p.FileSize.ToLower().Contains(search.ToLower()) ||    
         p.FileModified.ToString().ToLower().Contains(search.ToLower())).ToList(); 

사용 : 뭔가 모델에 문제가 있습니다. 인터페이스 목록이 아니라 특정 유형의 목록이 필요하거나 인터페이스에 이러한 속성을 이동해야합니다.

예를 들어 LoadData 메서드는 인터페이스 목록을 반환하지만 예제에서는 특정 클래스 목록으로 사용합니다. 당신이 그것을 부를 수있는 그 후

public List<T> LoadData<T>() where T:IDirDetails 
{ 
    // return specific List 
} 

:

List<DirectoryItemInfo> data = LoadData<DirectoryItemInfo>(); 

당신이 캐스트가 필요하지 않습니다 당신은 그것을 변경할 수 있습니다. LoadData의 어딘가에서 어떤 요소를 반환할지 결정해야합니다.

+0

감사를 필터링 할 올바른을 제안 해주십시오 수 있습니다 방법을 달성하기 위해? –

+0

@ RahulNagrale 난 돈 ' 귀하의 전체 코드를 볼 수 있지만 답변에서 한 가지 제안을했지만, 실제로 정확히 무엇을하는지에 달려 있습니다. –

+0

LoadData(), Error :'CS0029 \t에서 'List '을 반환 할 때 오류가 표시됩니다.'System.Collections.Generic.List '유형을'System '으로 암시 적으로 변환 할 수 없습니다. .Collections.Generic.List ' –

0

'OfType'메서드를 사용하여 'DirectoryItemInfo'형식의 'data'목록에서 모든 항목을 가져올 수 있으며 'Where'의 결과를 'IDirDetails'목록으로 되돌릴 수 있습니다.

data = data.OfType<DirectoryItemInfo>() 
      .Where(p => 
        p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
        p.FileSize.ToLower().Contains(search.ToLower()) || 
        p.FileModified.ToString().ToLower().Contains(search.ToLower())) 
      .ToList<IDirDetails>(); 
0

사용자 인터페이스로 정의 된 멤버 만 액세스 할 수 있습니다. 해당 인터페이스의 구체적인 구현 멤버에 액세스해야하는 경우 구체 구현의 인스턴스가 필요합니다 (예 : DirectoryDetail 또는 DirectoryItemInfo의 인스턴스)

다른 유형으로 캐스팅 할 때 몇 가지 작업을 수행 할 수 있습니다 회원은 말했다,하지만 당신은 여전히 ​​어떤 식 으로든에서 구체적인 구현의 인스턴스를 액세스하는.

0

사용 OfType이 형에게 대답 선생님에 대한

List<IDirDetails> data = LoadData();     
int totalRecords = data.Count; 

if (!string.IsNullOrEmpty(search) && !string.IsNullOrWhiteSpace(search)) 
{ 
    // Apply search 
    data = data.OfType<DirectoryItemInfo>().Where(p => p.FileName.ToString().ToLower().Contains(search.ToLower()) || 
          p.FileSize.ToLower().Contains(search.ToLower()) ||    
          p.FileModified.ToString().ToLower().Contains(search.ToLower())).Cast<IDirDetails>().ToList(); 
} 
+0

목록에'DirectoryDetails'가 있으면'Cast'가 작동하지 않습니다. – xwlantian