How to clear default select clause on IQueryable resultset - c#

If I have a page class that returns an IQueryable result set like:
protected virtual IQueryable<EntityResult> GetEntities(ETBDataContext pContext)
{
return from e in pContext.Entities
where e.SectionId == SectionId && e.StatusCode == "Published"
orderby e.PublishDate descending
select new EntityResult
{
EntityId = e.Id,
Excerpt = e.Excerpt,
Name = e.Name,
PublishDate = e.PublishDate,
ShortDescription = e.ShortDescription
};
}
If I call this method in a inherited class, How can I clear the select and just get the ShortDescription?
public void IQueryable<EntityResult> GetResult(ETBDataContext pContext)
{
IQueryable<EntityResult> pQuery = base.GetEntities(pContext);
//right here: how can I just return the ShortDescription Only?
return pQuery;
}
I am using the default GetEntities() to do the standard select operation for default queries, but on some calls I would like to get just the specific data that I need.
Is this possible? are there other ways? Thanks in advance!!

You can try
pQuery = pQuery.Select(e => new EntityResult {
ShortDescription = e.ShortDescription
});
I'm pretty sure that this won't select the other columns.

Related

Some values in LINQ Query Statement aren't saved correctly to class with subsonic 3

I am developing a MVC 3 Application which uses Subsonic 3 for accessing the database.
My Problem is, i don't understand why the Enum "GlobalType" is not being written into the property.
Everytime i check, the value is 0 instead of "One".
The "Name" property contains the "DateCreated" value.
The "DateCreated" property contains a new DateTime instance.
No other fields, as far as i'm aware of, are doing this.
There is no logic inside of the ViewItemModel, it's just a class with properties.
If i add them after this method manually, everything works.
Maybe someone encountered something similar with subsonic (if it even is subsonic itself, maybe i'm making a mistake)?
I have this method in the Backend:
public IEnumerable<ViewItemModel> LoadView(int registratorId)
{
var itemModel = from item in _itemQuery
join header in _headerQuery on item.HeaderID equals header.ID
where header.RegistratorID == registratorId && !(from hidden in _headerHiddenQuery where hidden.ItemID == item.ID && hidden.Type == GlobalType.One && hidden.RegistratorID == registratorId select hidden.ID).Any()
orderby item.ID descending
select new ViewItemModel()
{
Type = GlobalType.One,
ID = item.ID,
Name = header.Name,
DateCreated = header.DateCreated,
TypeOfTransport = header.TypeOfTransport,
TransportType = item.TransportType,
Count = (from subItems in _subItemQuery where subItems.ItemID == item.ID select subItems.ID).Count(),
// For Status
IsArchived = header.IsArchived,
IsCanceled = header.IsCanceled,
Process = header.Process,
End = header.End,
IsPublished = header.IsPublished,
OpenFrom = header.OpenFrom,
OpenTill = header.OpenTill,
IsNextStarted = header.IsNextStarted
};
return itemModel.ToList();
}
Update:
The GlobalType enum looks like this
public enum GlobalType
{
One = 1,
Two = 2,
Individual = 3
}
If i add them manually, i changed the return statement for this:
var result = itemModel.ToList();
foreach (var item in result)
{
var headerId = _itemQuery.Where(it => it.ID == item.ID).Select(it => it.HeaderID).FirstOrDefault();
var created = _itemQuery.Where(it => it.ID == item.ID).Select(it => it.DateCreated).FirstOrDefault();
var name = _headerQuery.Where(it => it.ID == headerId).Select(it => it.Name).FirstOrDefault();
item.AnnouncementType = GlobalType.One;
item.Name = name;
item.DateCreated = created;
}
return result;
try sample code:
public int enum GlobalType
{
One = 1,
Two = 2,
Individual = 3
}
//enum value Convert to int or other data type using casting
item.AnnouncementType = (int) GlobalType.One;
//Suppose if condition using
if((GlobalType)item.AnnouncementType==GlobalType.One)
{
//your code
}
Thanks to DaveParsons comment, i managed to create a workaround.
In this case, the code will have to iterate twice through the list of found elements, but won't load the entire table into memory.
Since there is a bug (throwing exception) with creating an anonymous object containing multiple classes like so:
select new { item, header, subItems }
I managed to get all the data needed, by manually assigning what i need like so:
public IEnumerable<ViewItemModel> LoadView(int registratorId)
{
var itemModel = from item in _itemQuery
join header in _headerQuery on item.AnnouncementHeaderID equals header.ID
where header.RegistratorID == registratorId && !(from hidden in _headerHiddenQuery where hidden.ItemID == item.ID && hidden.Type == GlobalType.One && hidden.RegistratorID == registratorId select hidden.ID).Any()
orderby item.ID descending
select new {
Type = GlobalType.One,
ID = item.ID,
Name = header.Name,
DateCreated = header.DateCreated,
TypeOfTransport = header.TypeOfTransport,
TransportType = item.TransportType,
Count = (from subItems in _subItemQuery where subItems.ItemID == item.ID select subItems.ID).Count(),
// For Status
IsArchived = header.IsArchived,
IsCanceled = header.IsCanceled,
Process = header.Process,
End = header.End,
IsPublished = header.IsPublished,
OpenFrom = header.OpenFrom,
OpenTill = header.OpenTill,
IsNextStarted = header.IsNextStarted
};
return itemModel
.ToList()
.Select(it => new ViewItemModel() {
Type = it.Type,
ID = it.ID,
Name = it.Name,
DateCreated = it.DateCreated,
TypeOfTransport = it.TypeOfTransport,
TransportType = it.TransportType,
Count = it.Count,
// For Status
IsArchived = it.IsArchived,
IsCanceled = it.IsCanceled,
Process = it.Process,
End = it.End,
IsPublished = it.IsPublished,
OpenFrom = it.OpenFrom,
OpenTill = it.OpenTill,
IsNextStarted = it.IsNextStarted
})
.ToList();
}
Notice: The return value of the query is an anonymous object with every single necessary field declared.
After the database returned all fields with the same name as in the database (model), we then have to force execution with ".ToList()" or something similar (deferred execution?).
Since the data is now in memory, we can assign the values from the anonymous object to the original class that was intended for this purpose.
I am sure there is a more reliable way using reflection, but this is what i have come up with.

Setting the value to null using LINQ in list of list

I have a class
public class ReceiptDisplayInfo
{
public string ReceiptItemFor{get;set;}
public string ReceiptItemCategory{get;set;}
public string ReceiptItemReference{get;set;}
public string ReceiptRowCategory{get;set;}
public string ReceiptAmount{get;set;}
}
I have a list
List<List<ReceiptDisplayInfo>> dataSourceToBind ;
My requirement : For every List , if ReceiptRowCategory="Payment" , I have to set the value of ReceiptItemForm,ReceiptItemCategory to blank or null in dataSourceToBind .
I am doing using for loop but this is not the most appreciated approach.
Please assist me in doing using LINQ/Lambda Expression.
dataSourceToBind.ForEach(x =>
{
var innerList = x;
innerList.ForEach(y =>
{
if (y.ReceiptRowCategory == "Payment")
{
y.ReceiptItemFor = null;
y.ReceiptItemCategory = null;
}
});
});
I guess just 2 ForEach calls would suffice, no need to use LINQ here. However, since the transformation logic is quite complicated, I think you should extract it as a method:
private void SomeMethod(ReceiptDisplayInfo info) { // please name this appropriately
if (info.ReceiptRowCategory == "Payment") {
info.ReceiptItemForm = null;
info.ReceiptItemCategory = null;
}
}
And then,
dataSourceToBind.ForEach(x => x.ForEach(SomeMethod));
You can use below code to achieve this-
((from l in list
where l.ReceiptItemCategory == "payment"
select new ReceiptDisplayInfo()
{
ReceiptItemFor = null,
ReceiptItemCategory = null,
ReceiptItemReference = l.ReceiptItemReference,
ReceiptRowCategory = l.ReceiptRowCategory,
ReceiptAmount = l.ReceiptAmount
}).Union(from l in list
where l.ReceiptItemCategory != "payment"
select l)).ToList();

Convert Object to List

I want convert object to list of myclass, which object is return from linq query.
object list = detailManager.GetMutabakatDetailListByMutabakat(oMutabakat, true);
List<CurrentAccount> accountList = ??
GetMutabakatDetailListByMutabakat method like this;
public object GetMutabakatDetailListByMutabakat(Mutabakat mutabakat, bool Gonderen)
{
var detayIdList = this.Context.MutabakatDetay.Where(s => s.MutabakatId == mutabakat.MutabakatId).Select(s => s.MutabakatDetayId).ToList();
var CariEkstreList =
(from ekstre in this.Context.CariHesapEkstre
join detay in this.Context.MutabakatDetay on ekstre.MutabakatDetayId equals detay.MutabakatDetayId
where detayIdList.Contains(ekstre.MutabakatDetayId.Value) && ekstre.GonderenMukellefFirmaId == mutabakat.GonderenMukellefFirmaId
select new
{
MutabakatDetayId = ekstre.MutabakatDetayId,
MutabakatVar = ekstre.MutabakatVar,
AlanFirmaId = ekstre.AlanFirmaId,
GonderenMukellefFirmaId = ekstre.GonderenMukellefFirmaId,
KayitTarihi = ekstre.KayitTarihi,
DonemYil = ekstre.DonemYil,
DonemAy = ekstre.DonemAy,
Degistirildi = ekstre.Degistirildi,
CariHesapEkstreId = ekstre.CariHesapEkstreId,
AktaranKullaniciId = ekstre.AktaranKullaniciId,
AktarimId = ekstre.AktarimId,
AktarimTarihi = ekstre.AktarimTarihi,
BakiyeTur = ekstre.BakiyeTur,
BelgeNo = ekstre.BelgeNo,
BelgeTarihi = ekstre.BelgeTarihi,
BelgeTur = ekstre.BelgeTur,
IslemTarihi = ekstre.IslemTarihi,
ParaBirimi = ekstre.ParaBirimi,
TLTutar = ekstre.BakiyeTur == "B" ? ekstre.TLTutar * -1 : ekstre.TLTutar,
Tutar = ekstre.BakiyeTur == "B" ? ekstre.Tutar * -1 : ekstre.Tutar
}).ToList();
return CariEkstreList;
}
It depends on what list actually is:
A) if detailManager.GetMutabakatDetailListByMutabakat(oMutabakat, true) returns IEnumerable<CurrentAccount> then all you have to do is to add .ToList():
List<CurrentAccount> accountList = detailManager
.GetMutabakatDetailListByMutabakat(oMutabakat, true)
.ToList();
B) if detailManager.GetMutabakatDetailListByMutabakat(oMutabakat, true) returns IEnumerable<SomeObject> and SomeObject can be cast to CurrentAccount then
List<CurrentAccount> accountList = detailManager
.GetMutabakatDetailListByMutabakat(oMutabakat, true)
.OfType<CurrentAccount>()
.ToList();
C) Finally, in the general case you have to implement .Select:
List<CurrentAccount> accountList = detailManager
.GetMutabakatDetailListByMutabakat(oMutabakat, true)
.Select(item => GetAccountFromItem(item)) //TODO: implement Select
.ToList();
Thanks everyone, i solved my problem with using reflaction.
firstly, object casted to IList
List<CariHesapEkstre> senderExtractList = GetExtractList((IList)detayManager.GetMutabakatDetayListByMutabakat(oMutabakat, true));
private List<CariHesapEkstre> GetExtractList ( IList tempList )
{
List<CariHesapEkstre> returnList = new List<CariHesapEkstre>();
foreach ( var item in tempList )
{
CariHesapEkstre extract = new CariHesapEkstre();
foreach ( PropertyInfo prop in item.GetType().GetProperties() )
{
foreach ( PropertyInfo prop2 in extract.GetType().GetProperties() )
{
if ( prop2.Name == prop.Name )
{
prop2.SetValue(extract, prop.GetValue(item));
}
}
}
returnList.Add(extract);
}
return returnList;
}
There are few things I can say,
What does your method GetMutabakatDetailListByMutabakat return? Does it have to be object?
As its name implies - if a methods name is Get...List I would expect it to return a list, not an object. If you can, first change that behaviour then you'll be ok.
If that method is written by someone else(that you cannot change the behaviour) then you should play with casting operations as the others suggest, but you can only do this if the underlying object is really of type List<CurrentAccount>.
And if the underlying object is not even of type List<CurrentAccount> then you should learn what the object structure is(another class, anonymous object, or dynamic) then we can work something out.
After Update
With the update to your question I can see that you are returning a list of anonymous objects. But isn't it actually CurrentAccount?
So if you select it as following:
public List<CariHesapEkstre> GetMutabakatDetailListByMutabakat ( Mutabakat mutabakat, bool Gonderen )
{
var detayIdList = this.Context.MutabakatDetay.Where(s => s.MutabakatId == mutabakat.MutabakatId).Select(s => s.MutabakatDetayId).ToList();
var CariEkstreList =
( from ekstre in this.Context.CariHesapEkstre
join detay in this.Context.MutabakatDetay on ekstre.MutabakatDetayId equals detay.MutabakatDetayId
where detayIdList.Contains(ekstre.MutabakatDetayId.Value) && ekstre.GonderenMukellefFirmaId == mutabakat.GonderenMukellefFirmaId
/// here you only need to use object initializer for CariHesapEkstre like just below
select new CariHesapEkstre
{
MutabakatDetayId = ekstre.MutabakatDetayId,
MutabakatVar = ekstre.MutabakatVar,
...
Tutar = ekstre.BakiyeTur == "B" ? ekstre.Tutar * -1 : ekstre.Tutar
} ).ToList();
return CariEkstreList;
}
Last Update
I see what you are trying to do, you want a method to do the hardwork for you. So you can check this tool called automapper. It does what you are trying to do. But still it's a hard work for your code too.
But if you are only trying to convert an object to a list you can use the code below.
public List<CariHesapEkstre> ConvertToDesiredType ( object list )
{
return ( (IEnumerable<dynamic>)list ).Select(item => new CariHesapEkstre
{
MutabakatDetayId = item.MutabakatDetayId,
MutabakatVar = item.MutabakatVar,
...
}).ToList();
}

WP7 Sterling Database DateTime Index

I am using a Sterling Database and have defined a class and index as follows
public class SingleEventDB :TimetableEventDB
{
public DateTime EventDateTime { get; set; }
}
CreateTableDefinition<SingleEventDB, string>(k => k.UniqueId)
.WithIndex<SingleEventDB,DateTime,string>("BYDATETIME",i=>i.EventDateTime)
I access this like this
public List<SingleEvent> GetAllSingleEvents(DateTime StartDate)
{
var allSingleEvents = new List<SingleEvent>();
var result =
from eveItemDB in App.MyDatabase.Query<SingleEventDB, DateTime, string>("BYDATETIME")
where (eveItemDB.Index >= StartDate)
select new SingleEvent
{
UniqueId = eveItemDB.LazyValue.Value.UniqueId,
NextDateTime = eveItemDB.Index,
Details = eveItemDB.LazyValue.Value.Details,
Location = eveItemDB.LazyValue.Value.Location
};
foreach (SingleEvent eveItem in result)
{
allSingleEvents.Add(eveItem);
}
return allSingleEvents;
}
However whilst the where clause is correctly filtering out the objects which are earlier than the input date, they are returned in the order that they were created, rather than in the index (DateTime) order.
Is this expected, or am I doing something wrong.
And is there a way to insert an orderby clause in t.
Seems you missed the Enumerable.ToList extension method! And yes, you could simply add orderby eveItemDB.Index to your code, like this:
public List<SingleEvent> GetAllSingleEvents(DateTime StartDate)
{
var result =
from eveItemDB in App.MyDatabase.Query<SingleEventDB, DateTime, string>("BYDATETIME")
where (eveItemDB.Index >= StartDate)
orderby eveItemDB.Index
select new SingleEvent
{
UniqueId = eveItemDB.LazyValue.Value.UniqueId,
NextDateTime = eveItemDB.Index,
Details = eveItemDB.LazyValue.Value.Details,
Location = eveItemDB.LazyValue.Value.Location
};
return result.ToList();
}

LINQ expression works good in LINQPad, but in Silverlight return empty result

This is a simple left outer join in LINQ (like the MS example).
It works good in LINQPad:
from x in Nevtars
join c in Tetsziks on x.NevtarID equals c.NevtarID into ctemp
from subc in ctemp.DefaultIfEmpty()
select new { x.Nev, subc.Tetszes }
The result:
-----------------
Nev Tetszes
Őszike 1
Őzike null
Pintyőke null
Regő null
Rezső null
Szellő null
Szellőke 2
This expresion in Silverlight DomainSource side:
public IQueryable<MyP> GetTetszik()
{
var q2 = from x in this.Context.Nevtars
join c in this.Context.Tetszik on x.NevtarID equals c.NevtarID into ctemp
from subc in ctemp.DefaultIfEmpty()
select new MyP
{
Nev = x.Nev,
Tetszes = (subc == null ? 0 : (Int32)subc.Tetszes)
};
return q2;
}
public class MyP
{
[Key]
public string Nev { get; set; }
public int Tetszes { get; set; }
}
And in the "Entity side":
DomainService1 ctx2 = new DomainService1();
xxxGrid.ItemsSource = ctx2.MyPs;
var q2 = ctx2.GetTetszikQuery();
ctx2.Load(q2);
The result will be an empty grid... :(
Please help me!
Thanks!
Does the domain service provide a way for the ItemsSource to catch the changes? If not, reassign it to the ItemsSource after you grabbed the data from the database.

Categories