2016-07-05 11 views
0

Так у меня есть этот запрос, LinqВозможно ли удалить свойство или по крайней мере установить его null из объекта в запросе без изменения его типа?

var users = from user in dbContext.Users 
      where user.IsPublic 
      select user; 

Проблема в том, что этот пользователь имеет другие свойства я не хочу вернулся, такие как passwordHash или по электронной почте.

выбор Также в new User{Id=user.Id, First...} результатов в этой классическую ошибку .. наверное потому, что пользователь расширяет AspNetIdentityUser

Субъект или сложного типа «MyProject.User» не может быть построен в LINQ к Entities запросу.

Я знаю, что я мог бы создать новый класс и выбрать в нем, но я хочу возвращаемый быть типа User

Можно ли удалить свойство/поле из User по-крайней мере, установить его недействительным, если делая запрос без изменения его типа?

+2

Посмотрите анонимные типы https://msdn.microsoft.com/ru-ru/library/bb397696.aspx –

+0

Вы пробовали просто 'new {Id = user.Id, First ...}' Создавать анонимный объект –

+0

Я попробовал его прямо сейчас ... отбрасывая его на пользователя приложения, дает мне null – konzo

ответ

2

Вы можете выбрать все необходимые свойства для анонимного типа, материализовать результат, а затем использовать его, чтобы создать список пользователей. Первый запрос использует синтаксис SQL, синтаксис второй цепочки.

private static void Main(string[] args) 
{ 
    List<User> Users = new List<User>() 
    { 
     new User {Id = 1, Name = "N1", IsPublic = true}, 
     new User {Id = 2, Name = "N2", IsPublic = true}, 
     new User {Id = 3, Name = "N3"} 
    }; 

    var users1 = from u in (from user in Users 
     where user.IsPublic 
     select new {user.Id, user.Name}).ToList() 
     select new User {Id = u.Id, Name = u.Name}; 

    var users2 = 
     Users.Where(x => x.IsPublic) 
      .Select(user => new {user.Id, user.Name}) 
      .ToList() 
      .Select(x => new User {Id = x.Id, Name = x.Name}); 

    Console.ReadLine(); 

} 
+0

Это работает, но дает мне IEnumerable как возвращаемый тип, All i хотел был IQueryable .. спасибо, я буду придерживаться этого, но мне действительно нужны функции от IQueryable – konzo

1

Очевидно, вам не разрешено создавать новые объекты, которые сопоставляются с базой данных в выражении Linq To Entities.

Это предотвращает выбор частичных результатов в сопоставленные классы. Я бы посоветовал вам создать отдельный класс и вернуть его, а вместо этого, используя тот же класс, эта сигнатура функции становится очень вводящей в заблуждение - можно ожидать, что она вернет полный пользовательский объект.

Вы можете обойти эту проблему, выбрав нужные значения, а затем создав пользователей вне запроса.

Попробуйте это:

public List<User> GetPublicUsers() 
{ 
    var existingUsers = dbContext.Users 
     .Where(u => u.IsPublic); 

    var result = new List<User>(); 
    foreach(var existingUser in existingUsers) 
    { 
     result.Add(new User { Id = existingUser.Id, ...})); 
    } 
    return result; 
} 
+0

Это дает ошибку 'Объект или сложный тип «MyProject.User» не может быть сконструирован в запросе LINQ to Entities', потому что я расширяю aspIdentityUser – konzo

+0

Упс, он будет работать. Я обновил свой ответ. –

+0

Я просто скопировал ваш код и получил 'Тело MyProject.Users() 'не может быть блоком итератора, потому что' IQueryable 'не является типом интерфейса итератора' – konzo

0

Ну Это привлекает слишком много из двух ответов .. см возвращаемого типа должен быть IQueryable это еще не завершено, как я хотел бы скрыть некоторые столбцы полностью, я только что удался изменить их значение .. я действительно ненавижу breezejs за заставляя нас выставить слишком много нашей схемы

public IQueryable<User> Users() 
{ 

    var users = from user in _db.Context.Users 
     where user.IsPublic 
     select user; 


    foreach (var user in users) 
     { 
      user.PasswordHash = null; 
      user.PhoneNumber = null; 
      user.Logins.Clear(); 
      user.Email = null; 
      user.AccessFailedCount = 0; 
      user.Roles.Clear(); 
      user.SecurityStamp = null; 
      user.TwoFactorEnabled = user.EmailConfirmed = user.PhoneNumberConfirmed = false; 
      user.Claims.Clear(); 
     } 
     return users; 
    } 

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