Получить значение из c# анонимного типа, используя HierarchyId - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь использовать SqlHierarchyId в. net

В моем контроллере я использую анонимный тип для получения значения из базы данных.

[HttpGet("{id}")]
public async Task<ActionResult<object>> GetDomain(int id)
{
    object domain = from x in _context.Domains.Where(x => x.DomainId == id)
                 select new
                 {
                     Id = x.DomainId,
                     Name = x.DomainName,
                     Type = x.DomainTypeId,
                     Parent = x.Parentt,
                     Path = x.Level.ToString()
                 };
    return domain;
}

Затем я хочу получить путь преобразовать в SqlHierarchyId для применения различных методов, поддерживаемых. Net

Я пробовал Отражение:

System.Type type = domain.GetType();
string strNode = (string) type.GetProperty("Path").GetValue(domain, null);

У меня есть эта ошибка:

System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.

Когда я отлаживал свой код, я обнаружил, что strNode является нулевым, но домен содержит все значения, которые мне нужны, когда я тестирую с Почтальон.

Я пытаюсь Dynami c:

dynamic dyn= domain;
string strNode= dyn.Path;

И у меня есть эта ошибка:

Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable << > f__AnonymousType1> 'не содержит определения для' Path

. Я также пробую несколько других предложений (клон, определите анонимный тип как класс ...), найденных по аналогичному вопросу, но безрезультатно.

Примечание: Я пытаюсь использовать anon тип ymous, потому что я не могу получить значение, когда direclty использует мою модель. У меня есть ошибка приведения типа.

Невозможно привести объект типа «Microsoft.SqlServer.Types.SqlHierarchyId» к типу «Microsoft.Data.SqlClient.Server.IBinarySerialize».

Но с анонимным Я могу получить значения, поэтому хочу получить доступ к этим значениям и передать их моей модели.

Ответы [ 2 ]

0 голосов
/ 11 марта 2020

Основная проблема или допущение связано с возвращаемым значением из действия GetDomain. Linq Где возвращает коллекцию (типа, к которому вы применяете этот фильтр), и, следовательно, в этом случае домен будет поддерживать анонимный IQueryable, а не один домен.

Если вы хотите вернуть один домен, используйте FirstOrDefault. как показано ниже:

[HttpGet("{id}")]
public async Task<ActionResult<object>> GetDomain(int id)
{   
    object domain = (from x in _context.Domains.Where(x => x.DomainId == id)
                 select new
                 {
                     Id = x.DomainId,
                     Name = x.DomainName,
                     Type = x.DomainTypeId,
                     Parent = x.Parentt,
                     Path = x.Level.ToString()
                 }).FirstOrDefault();
    /*    
    // Or use FirstOrDefault in place of Where as shown below                
     object domain = (from x in _context.Domains
                 select new
                 {
                     Id = x.DomainId,
                     Name = x.DomainName,
                     Type = x.DomainTypeId,
                     Parent = x.Parentt,
                     Path = x.Level.ToString()
                 }).FirstOrDefault(x => x.Id == id);
    */
    return domain;
}

После этого изменения оставшаяся часть кода должна работать как положено.

0 голосов
/ 11 марта 2020

Ваша проблема в том, что domain на самом деле IEnumerable анонимного объекта. Оператор select генерирует IEnumerable, даже если есть только один экземпляр.

Если вы хотите получить реальный объект, вы можете получить его следующим образом.

var obj = domain.FirstOrDefault();

или

var obj = domain.Single();

А затем выполните поиск по отражению:

var type = obj.GetType();
var strNode = (string) type.GetProperty("Path").GetValue(obj, null);
...