I want to add a value in IQueryable get from another IQueryable here is my code
var queryReturnRequest = query.Include(x => x.Assignment)
.ThenInclude(x => x.Asset).Select(x => new ReturnRequestDto
{
AssetCode = x.Assignment.Asset.Code,
AssetName = x.Assignment.Asset.Name,
Id = x.Id,
ReturnDate = x.ReturnDate,
AssignedDate = x.Assignment.AssignedDate,
State = x.State,
UserRequestId = x.UserRequestId,
UserAcceptId = x.UserAcceptId,
RequestedBy = userList.FirstOrDefault(u => u.Id == x.UserRequestId) != null ? userList.FirstOrDefault(u => u.Id == x.UserRequestId).UserName : "",
AcceptedBy = userList.FirstOrDefault(u => u.Id == x.UserAcceptId) != null ? userList.FirstOrDefault(u => u.Id == x.UserAcceptId).UserName : "",
});
But it was crashed and return error 500, I found out that was because of userList.FirstOrDefault but when I console.log() it just work fine. So what wrong with it and is there another way to add it in IQueryable ?
I tried to user for loop to add IQueryable but it just return to null after get our of loop.
Try rewrite query in the following way. Also note that Select discards Includes, so avoid them in such case.
var queryReturnRequest = query
.Select(x => new ReturnRequestDto
{
AssetCode = x.Assignment.Asset.Code,
AssetName = x.Assignment.Asset.Name,
Id = x.Id,
ReturnDate = x.ReturnDate,
AssignedDate = x.Assignment.AssignedDate,
State = x.State,
UserRequestId = x.UserRequestId,
UserAcceptId = x.UserAcceptId,
RequestedBy = userList.Where(u => u.Id == x.UserRequestId).Select(x => x.UserName).FirstOrDefault() ?? "",
AcceptedBy = userList.Where(u => u.Id == x.UserAcceptId).Select(x => x.UserName).FirstOrDefault() ?? "",
});
Related
Good Morning,
I have a problem with the performance if i use include.
Have a look at the following query, if I load the data from the include (x.Server_Item.itemType) the query needs like 980ms.
If i remove them, the query needs 51ms.
980ms:
using (var db = new dbContext())
{
var items = db.Characters_Inventory
.Where(x => x.charId == charId && x.itemLocation == ItemLocationInventory)
.Include(p => p.Server_Items)
.AsSplitQuery()
.Select(x => new
{
itemId = x.id,
x.itemName,
x.nameTag,
x.itemAmount,
x.itemLocation,
x.isItemEquipped,
x.itemCategory,
x.metaId,
x.metaTag0,
x.metaTag1,
itemType = x.Server_Items.itemType,
itemSubType = x.Server_Items.itemSubType,
itemClothesType = x.Server_Items.Server_Clothes.type,
itemPicName = x.Server_Items.itemPicSRC,
itemWeight = x.Server_Items.itemWeight,
itemGender = x.Server_Items.Server_Clothes.gender,
isItemUseable = x.Server_Items.isItemUseable,
isItemDroppable = x.Server_Items.isItemDroppable,
isItemGiveable = x.Server_Items.isItemGiveable,
isItemStorable = x.Server_Items.isItemStorable,
isItemStackable = x.Server_Items.isItemStackable,
isItemShowable = x.Server_Items.isItemShowable,
isItemNameable = x.Server_Items.isItemNameable,
isItemPlaceable = x.Server_Items.isItemPlaceable,
//isClothesTypeEquipped = IsClothesTypeEquipped(charId, x.id),
isClothesSwitchable = x.Server_Items.Server_Clothes.altClothesName != "" ? true : false
//isWeaponTypeEquipped = IsWeaponTypeEquipped(charId, x.id),
//charName = Characters.GetCharacterName(x.metaId)
}).AsNoTracking().ToList();
return JsonConvert.SerializeObject(items);
}
50ms:
using (var db = new dbContext())
{
var items = db.Characters_Inventory
.Where(x => x.charId == charId && x.itemLocation == ItemLocationInventory)
.Include(p => p.Server_Items)
.AsSplitQuery()
.Select(x => new
{
itemId = x.id,
x.itemName,
x.nameTag,
x.itemAmount,
x.itemLocation,
x.isItemEquipped,
x.itemCategory,
x.metaId,
x.metaTag0,
x.metaTag1
}).AsNoTracking().ToList();
return JsonConvert.SerializeObject(items);
}
I tried with AsSplitQuery and without AsSplitQuery.
Maybe nice to know: On the included table (Server_Items) is alrdy a table included.
Thanks in advance.
Sincerely
I want to sort the data based on CreatedUtc time. I have tried to use Reverse function, it seems to work out but still looking for some alternate option.
var result = _participantRepo.AsQueryable().Where(x => x.Id == ParticipantId).SelectMany(x =>
x.Relations).ToList().Where(x => x.UserId != AppUserId).Select(r => new RelationVM
{
IsOwner = r.UserId == participant.CreatedByUserId,
FirstName = r.FirstName,
LastName = r.LastName,
Email = r.Email,
UserId = r.UserId,
RelationType = r.RelationType,
Role = r.Role,
IsAccepted = r.IsAccepted,
AvatarUrl = r.AvatarUrl,
CreatedUtc = r.CreatedUtc
}).Reverse().ToList();
There are 2 things you need to concern:
You can sort the elements of a sequence by using OrderBy
You should not .ToList() when you have not done, So you might to read LINQ deferred (or immediate?) execution to have a better understanding.
As a result, your query should look like this
var result = _participantRepo.AsQueryable().Where(x => x.Id == ParticipantId).SelectMany(x =>
x.Relations).Where(x => x.UserId != AppUserId).Select(r => new RelationVM
{
IsOwner = r.UserId == participant.CreatedByUserId,
FirstName = r.FirstName,
LastName = r.LastName,
Email = r.Email,
UserId = r.UserId,
RelationType = r.RelationType,
Role = r.Role,
IsAccepted = r.IsAccepted,
AvatarUrl = r.AvatarUrl,
CreatedUtc = r.CreatedUtc
}).Reverse().OrderBy(g => g.CreatedUtc).ToList();
How about .OrderBy(g => g.CreatedUtc) ?
Please look at my code below
var result = (from c in db.vCompanies
where id == c.id
from user in db.Users
select new ViewCompanyModel()
{
Id = c.id,
Descripton = c.Descripton,
Name = c.Name,
ImageLink = c.ImageLink,
AdminEmail = c.Email,
Users = db.eUsers
.Where(o => o.CompanyName.Equals(c.Name))
.Select(o => new UserManageViewModel.UserViewModel
{
Id = o.UserId,
Name = o.LastName,
Email = o.Email,
Company = o.CompanyName,
ListOfRoles = user.AspNetUsers.AspNetRoles.Select(x=>x.Name).ToList()
})
}).FirstOrDefault();
I receive not correct data in ListOfRoles - I receive data only of first user.
I tried to add something like this
Where(x=>x.UserId == o.UserId)
I also tried change for this
ListOfRoles = db.Users.Where(x=>x.UserId == o.UserId).Select(x=>x.AspNetUsers.AspNetRoles)
But in this case I can't select x.Name.
I am doing something wrong.
Please advise me.
if(result != null)
{
foreach (var user in result.Users)
{
var roles = db.Users.Where(x => x.UserId == user.Id).Select(x => x.AspNetUsers.AspNetRoles).FirstOrDefault();
user.ListOfRoles = roles.Select(x => x.Name).ToList();
}
}
This is the answer! It's work!
Anybody know how to work with Kendo TreeView and SignalR?
Because I have this:
#(Html.Kendo().TreeView().Name("vehicleList")
.DataTextField("Name")
.DataSource(ds => ds.SignalR()
.AutoSync(true)
.Transport(tr => tr.Promise("hubStart")
.Hub("hub")
.Client(c => c.Read("read2"))
.Server(s => s.Read("read2"))
)
.Schema(s => s.Model(m => {
m.Id("id");
m.Field("Name", typeof(string));
m.Children("Children");
m.HasChildren("HasChildren");
}))
)
)
But when try expand or select item I have error that treeview require server.create method. But I try only expand or select tree
My hub looks like:
var vehicle = allVehicle.Where(d => d.ParentId == null || d.ParentId == Guid.Empty)
.Select(v => new VehicleTree() {
Name = v.Name,
Id = v.Id,
hasChildren = false
}).ToList();
var groups = allVehicle.Where(d => d.ParentId != Guid.Empty).Select(g => new VehicleTree() {
Id = g.ParentId,
Name = g.GroupName,
hasChildren = true
}).Distinct().ToList();
foreach(var g in groups) {
g.Children = allVehicle.Where(v => v.ParentId == g.Id).Select(v => new VehicleTree() {
Name = v.Name,
Id = v.Id,
hasChildren = false
}).ToList();
}
var result = new List<VehicleTree>();
result.AddRange(groups);
result.AddRange(vehicle);
return result;
I have the following database code:
static IEnumerable<dynamic> GetData(bool withchildren) {
using (var model = new testEntities()) {
var res = default(IQueryable<dynamic>);
if (withchildren) {
res = model.UserSet
.Where(u => u.name != "")
.Select(u => new {
Name = u.name,
Email = u.email,
Groups = u.GroupSet.Select(g => new {
Name = g.name,
Id = g.Id
})
});
} else {
res = model.UserSet
.Where(u => u.name != "")
.Select(u => new {
Name = u.name,
Email = u.email
});
}
return res.ToList()
}
}
I would like to shrink the code and write it like this:
static IEnumerable<dynamic> GetData(bool withchildren) {
using (var model = new testEntities()) {
var res = default(IQueryable<dynamic>);
res = model.UserSet
.Where(u => u.name != "")
.Select(u => {
dynamic item = new {
Name = u.name,
Email = u.email
};
if(withchildren) {
item.Groups = u.GroupSet.Select(g => new {
Name = g.name,
Id = g.Id
});
}
return item;
});
return res.ToList();
}
}
But Visual Studio complains, that it cannot convert the lambda expression into an expression tree.
My question is, is there a way to accomplish that with the Entity Framework and Linq? I really wouldn't want to use ADO.net directly.
Maybe there is even a better version to shrink it, than the code that I imagine.
Here is a related question with Linq-To-Objects.
EDIT
Before someone asks, I use dynamic in the example code to make it a bit easier and faster.
EDIT 2
My goal with this approach is, to only query the fields I need to improve performance. Check http://www.progware.org/Blog/post/Slow-Performance-Is-it-the-Entity-Framework-or-you.aspx.
At the moment we use something like
static IEnumerable<dynamic> GetData(bool withchildren) {
using (var model = new testEntities()) {
var res = default(IQueryable<dynamic>);
res = model.UserSet
.Where(u => u.name != "")
.ToList();
return res;
}
}
And the performance is, according to Glimpse, horrible.
EDIT 3
Short side note, I made up some quick and dirty code. That is, why the foreach at the end was not needed. The actual code is not available at the moment.
Is there any reason you couldn't use:
res = model.UserSet
.Where(u => u.name != "")
.Select(u => new {
Name = u.name,
Email = u.email,
Groups = withchildren
? u.GroupSet.Select(g => new {
Name = g.name,
Id = g.Id
})
: null;
})
};
or perhaps:
res = model.UserSet
.Where(u => u.name != "")
.ToList() // ToList() here to enumerate the items
.Select(u => {
dynamic item = new {
Name = u.name,
Email = u.email
};
if(withchildren) {
item.Groups = u.GroupSet.Select(g => new {
Name = g.name,
Id = g.Id
});
}
return item;
});
One approach that would allow you to eliminate some code would be:
var res = model.UserSet.Where(u => u.name != "");
if (withchildren) {
res = res.Select(u => new {
Name = u.name,
Email = u.email,
Groups = u.GroupSet.Select(g => new {
Name = g.name,
Id = g.Id
})
});
} else {
res = res.Select(u => new {
Name = u.name,
Email = u.email
});
}
One of the most requested by community feature is support of multi-line expressions in EF,
however so far, you can use only conditional operator "?:" as well as wrap result in
one common type, so both your results will have to have "Groups" field.
Also there are an extensions to linq-providers such as https://www.nuget.org/packages/LinqKit/ ,
however they are based on own conventions so any developer should study it in depth before
taking advance in applying and supporting code written upon that extensions.