How Querying with EDM LINQ Method? - c#

How this LINQ Query syntax:
var city = from c in _db.SubCategories where c.KategorijaID == stateID select new { c.PodKategorijaID, c.NazivPodKategorije };
change to LINQ Method syntax?
Example
This is LINQ Query syntax:
using (var context = new SchoolDBEntities())
{
var L2EQuery = from st in context.Students
where st.StudentName == "Bill"
select st;
var student = L2EQuery.FirstOrDefault<Student>();
}
and this is LINQ Method syntax:
//Querying with LINQ to Entities
using (var context = new SchoolDBEntities())
{
var L2EQuery = context.Students.where(s => s.StudentName == "Bill");
var student = L2EQuery.FirstOrDefault<Student>();
}

var city = _db.SubCategories.Where(c => c.KategorijaID == stateID)
.Select(c => new { c.PodKategorijaID, c.NazivPodKategorije });

var city = _db.SubCategories.Where(c => c.KategorijaID == stateID)
.Select(c => new { c.PodKategorijaID, c.NazivPodKategorije });

Related

Entity Framework Include performance problems

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

LINQ to Entities does not recognize the method 'StaticMethod' method

I have a code like this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i) =>
new DocType()
{
Id = StaticMethod(d, c),
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == StaticMethod(d, c)).SomeValue
}
).ToArray()
}).ToArray();
}
But I get a "LINQ to Entities does not recognize the method 'StaticMethod' method, and this method cannot be translated into a store expression" exception. Does exist any way to pass a static value as a parameter? Something like this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i, string myValue = StaticMethod(d, c)) =>
new DocType()
{
Id = myValue,
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == myValue).SomeValue
}
).ToArray()
}).ToArray();
}
I can't modify DocType class constructor. Does exist any way?
Usually this is a matter of making sure you don't inline functions in linq-to-SQL expressions that can't be turned into valid SQL.
Try this:
using (var ws = new WebService())
using (var db = new EntityFrameworkModel())
{
var originalFolders = ws.GetFolders();
foo.folders = originalFolders.Select(c => new FolderType()
{
Id = c.Description,
Items = ws.ListDocs(c.Id)
.Select((d, i) =>
{
var id = StaticMethod(d, c);
return new DocType()
{
Id = id,
Order = i,
SomeValue = db.docs.Single(doc => doc.Id == id).SomeValue
};
}).ToArray()
}).ToArray();
}

Unable to Convert Linq to Lambda Notation

public ActionResult EditArticle(int id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var typeId = 0;
var catId = 0;
var subCatId = 0;
var viewModel = (from sa in ems.SupportArticles
join ssc in ems.SupportSubCategories on sa.SubCatID equals ssc.SubCatID
join sc in ems.SupportCategories on ssc.CatID equals sc.CatID
join st in ems.SupportTypes on sc.TypeID equals st.TypeID
where sa.ArcticleId == id
select new SupportArticleViewModel { supportArticle = sa, supportSubCat = ssc, supportCat = sc, supportType = st });
foreach (var vm in viewModel)
{
typeId = vm.supportType.TypeID;
catId = vm.supportCat.CatID;
subCatId = vm.supportSubCat.SubCatID;
}
I want to convert it into Lambda Notation.But, I am unable to do it.Please help.I am using SupportViewModel which contains property of SupportType,SupportCategory ,SupportSubCategoryand SupportArticle.
Following is functional way do query , you have to make use of join function and than you get data
var filteredArtciles = SupportArticles.Where(sa=> sa.ArcticleId == id);
var query =
SupportArticles.
Join(SupportSubCategories,sa => sa.SubCatID ,ssc => ssc.SubCatID,(sa, ssc) => new {sa,ssc}).
Join(SupportCategories,sassc => sassc.ssc.CatID ,sc=>sc.CatID ,(sassc, sc) => new {sassc,sc}).;
Join(SupportTypes,sasscsc => sasscsc.sc.TypeID ,st=>st.TypeID ,(sc, st) => new {sasscsc,st}).
Select(j=>
new SupportArticleViewModel
{
supportArticle = j.sasscsc.sassc.sa,
supportSubCat = j.sasscsc.sassc.ssc,
supportCat = j.sasscsc.sc,
supportType = j.st
}
));

Converting the Linq to Entity from query syntax to method syntax?

I have this LINQ to Entity:
var de = from dm in _context.DamageEvents
where dm.StatusID == statusId
group dm by new { dm.ClientId, dm.Client.ClientName, dm.SiteId, dm.Site.Name, dm.SiteObjectId } into g
select new
{
g.Key.ClientId,
g.Key.ClientName,
g.Key.SiteId,
g.Key.Name,
g.Key.SiteObjectId,
icon = g.Select(i=>i.SiteObject.ObjectModel.ObjectType.Icon).FirstOrDefault()
};
How can I convert the linq above to from query syntax to method syntax.
Any idea how can I implement it?
something like this?
var de = _context.DamageEvents.Where(dm => dm.StatusID == statusId)
.GroupBy(dm => new {dm.ClientId, dm.Client.ClientName, dm.SiteId, dm.Site.Name, dm.SiteObjectId})
.Select(g => new
{
g.Key.ClientId,
g.Key.ClientName,
g.Key.SiteId,
g.Key.Name,
g.Key.SiteObjectId,
icon = g.Select(i => i.SiteObject.ObjectModel.ObjectType.Icon).FirstOrDefault()
});

Entity Framework condition in select

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.

Categories

Resources