How to Join a table with a list NHibernate? - c#

I have a list of objects like this
public class MyList
{
public int recordNo { get; set; }
public bool IsValid { get; set; }
}
var result= (from pool in context.Table.Where(prdicate)
select new ResultEntity
{
guid = pool.guid,
isValid = myList.FirstOrDefault(no => no.guid == pool.guid).IsValid //It thorws an error here
}
the error is
System.NotSupportedException:
the error caused because IsValid assign
So I want to join the list with a table, to asssign some values on it. How can I do that?

Customer customerAlias = null;
Organization organizationAlias = null;
IList<Customer> customers = session.QueryOver(() => customerAlias)
.Left.JoinAlias(x => x.Organization, () => organizationAlias)
.Where(customer => customer.Name == "Customer Name")
.And(() => customerAlias.Age > 18)
.AndNot(() => organizationAlias.Name == "Forbidden Organization")
.List();

Related

Linq complex Inner Join

I want to join my data with linq inner join as:
[DataContract]
public class Data
{
[DataMember(Order = 0, IsRequired = false, EmitDefaultValue = false)]
public List<DataResultObject> Row { get; set; }
}
[DataContract]
public class DataResultObject
{
[DataMember]
public string NAME { get; set; }
[DataMember]
public string VALUE { get; set; }
[DataMember]
public string TYPE { get; set; }
}
List<Data> follow = (List<Data>)dataset_cache.Get("follow");//364 rows
List<Data> icerik = (List<Data>)dataset_cache.Get("icerik");//134854 rows
List<Data> follow_icerik = icerik.Join(follow,
i => i.Row.Where(w => w.NAME == "CrawlSourceId").Select(s => s.VALUE),
f => f.Row.Where(w => w.NAME == "crawl_source_id").Select(s => s.VALUE),
(i, f) =>
new Data
{
Row = i.Row.Concat(nf.Row).ToList()
}
).Take(5).ToList();
But it returns empty, how to use inner join when we have list in "on" clause ?
Try this:
List<Data> follow_icerik = icerik.Concat(
icerik.SelectMany(e => e.Row)
.Where(w => w.NAME == "CrawlSourceId")
.Join(follow.SelectMany(e => e.Row)
.Where(w => w.NAME == "crawl_source_id"),
i => i.VALUE,
f => f.VALUE,
(i, f) =>
new List<DataResultObject> { i, f }
).Select(e => new Data { Row = e })
).ToList();
EDIT:
icerik.SelectMany(e=>e.Row) - select rows with data which we are needed
icerik.SelectMany(e=>e.Row).Where(w => w.NAME == "CrawlSourceId") - filter this data
... Join(... - join filtered data
In Join we also have to filter data before join: follow.SelectMany(e=>e.Row) .Where(w => w.NAME == "crawl_source_id")
i => i.VALUE,
f => f.VALUE, - fields on which we join data.

How to Convert Anonymous Type to List <dynamic> using Linq to SQL in C#

I'm new to C# and Linq.
Actually, I want to return anonymous types into list. anonymous types is contain of List, String, and DateTime. I tried with the code as below but its giving an error. please help and tell me what I am missing or suggest how can I achieve this.
//Error:
System.InvalidCastException: Specified cast is not valid..
//Edited C# Linq Code
public List<AuditInfo> GetScanAudit(object Id, DateTime? fromTime, DateTime? toTime, string type = null,
string user = null, Pager pager = null)
{
using (var ctx = new PlantDataContext())
{
var query = from audit in ctx.AuditLog
join ent in ctx.Scans on audit.RecordId equals ent.Id.ToString() into audits
from entaudits in audits.DefaultIfEmpty()
where audit.TypeFullName == "ABCD.DB.Model.Scan"
select new
{
audit,
entaudits
};
if (Id != null)
{
query = query.Where(x => x.audit.RecordId == Id.ToString());
}
if (fromTime.HasValue)
{
var tmp = new DateTimeOffset(fromTime.Value.ToUniversalTime());
query = query.Where(x => x.audit.EventDateUTC >= tmp);
}
if (toTime.HasValue)
{
var tmp = new DateTimeOffset(toTime.Value.ToUniversalTime());
query = query.Where(x => x.audit.EventDateUTC <= tmp);
}
if (!string.IsNullOrEmpty(type))
{
var parseEvent = (EventType)Enum.Parse(typeof(EventType), type);
query = query.Where(x => x.audit.EventType == parseEvent);
}
if (!string.IsNullOrEmpty(user))
{
query = query.Where(x => x.audit.UserName == user);
}
if (pager != null)
{
var totalRecords = query.Count();
pager.TotalRecords = totalRecords;
var data = query.Select(x =>
new AuditInfo
{
x.audit.TypeFullName, //Here Error Occurs
x.audit.UserName,//Here Error Occurs
x.audit.EventType,//Here Error Occurs
x.audit.EventDateUTC,//Here Error Occurs
#LogDetails = x.audit.LogDetails.ToList(), //Here Error Occurs
x.entaudits.Name,
#Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.Skip(pager.From)
.Take(pager.PageSize);
try
{
var list1 = data.ToList<AuditInfo>();
}
catch (Exception e)
{
}
var list = data.ToList<AuditInfo>();
pager.RecordCount = list.Count;
return list;
}
else
{
var list = query.Select(x =>
new AuditInfo
{
x.audit.TypeFullName,
x.audit.UserName,
x.audit.EventType,
x.audit.EventDateUTC,
#LogDetails = x.audit.LogDetails.ToList(),
x.entaudits.Name,
#Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.ToList<AuditInfo>();
return list;
}
}
}
When I debug the code totalRecords variable showing count 6, but is showing exception with message Specified cast is not valid at this line var list1 = data.ToList();
You have to cast the anonymous objects to dynamic.
To do this with linq you can use Cast<dynamic> linq method:
var list = query.Select(x =>
new
{
x.audit.TypeFullName,
x.audit.UserName,
x.audit.EventType,
x.audit.EventDateUTC,
#LogDetails = x.audit.LogDetails.ToList(),
x.entaudits.Name,
#Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.AsEnumerable()
.Cast<dynamic>()
.ToList<dynamic>(); \\ here exception occures
return list;
You can use strongly return type for your method like List<ClassName> instead of List<dynamic>
public List<ClassName> GetScanAudit(object Id, DateTime? fromTime, DateTime? toTime, string type = null, string user = null, Pager pager = null)
{
...
}
Then your query will be
var data = query.Select(x =>
new ClassName
{
TypeFullName = x.audit.TypeFullName,
UserName = x.audit.UserName,
EventType = x.audit.EventType,
EventDateUTC = x.audit.EventDateUTC,
LogDetails = x.audit.LogDetails.ToList(),
Name = x.entaudits.Name,
Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.Skip(pager.From)
.Take(pager.PageSize);
var list = data.ToList<ClassName>();
And your strongly type class look like
public class ClassName
{
public string TypeFullName { get; set; }
public string UserName { get; set; }
public string EventType { get; set; }
public DateTime EventDateUTC { get; set; }
public List<LogDetail> LogDetails { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Make sure the datatype of each property should match in your .Select clause in query
Edit:
if (pager != null)
{
var totalRecords = query.Count();
pager.TotalRecords = totalRecords;
var data = query.Select(x =>
new AuditInfo
{
TypeFullName = x.audit.TypeFullName,
UserName = x.audit.UserName,
EventType = x.audit.EventType,
EventDateUTC = x.audit.EventDateUTC,
LogDetails = x.audit.LogDetails.ToList(),
Name = x.entaudits.Name,
Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.Skip(pager.From)
.Take(pager.PageSize);
try
{
var list1 = data.ToList<AuditInfo>();
}
catch (Exception e)
{
}
var list = data.ToList<AuditInfo>();
pager.RecordCount = list.Count;
return list;
}
else
{
var list = query.Select(x =>
new AuditInfo
{
TypeFullName = x.audit.TypeFullName,
UserName = x.audit.UserName,
EventType = x.audit.EventType,
EventDateUTC = x.audit.EventDateUTC,
LogDetails = x.audit.LogDetails.ToList(),
Name = x.entaudits.Name,
Description = x.entaudits.Description
})
.OrderByDescending(x => x.EventDateUTC)
.ToList<AuditInfo>();
return list;
}

How to OrderBy nested Object value Linq

Object
namespace Example
{
public class ContractorAddValue
{
public Member Member { get; set; }
public List<Addresses> Addresses { get; set; }
public ICommand AddAddress { get; set; }
}
public class Addresses
{
public MemberAddress MemberAddress { get; set; }
public ICommand EditAddress { get; set; }
}
}
Query
public ObservableCollection<ContractorAddValue> GetContractorsOrderByCity()
{
var allContractors = (from c in db.Member where c.IsContrator == true select c).ToList();
//var allContractors2 = db.Member .Include(c => c.MemberAddress).SelectMany(c => c.MemberAddress).OrderBy(c => c.City).Select(c => c.Member ).ToList();
//var allContractors = (from c in db.Member where c.IsContrator == true select c).OrderBy(c => c.MemberAddress.OrderBy(x => x.City)).ToList(); <= dosent work
var listContractorAddValue = new ObservableCollection<ContractorAddValue>();
foreach (var i in allContractors)
{
var adressList = db.MemberAddress.Where(x => x.MemberId == i.MemberId).OrderBy(x => x.City).ToList();
ContractorAddValue contractorAddValue = new ContractorAddValue();
contractorAddValue.Member = i;
contractorAddValue.AddAddress = new BaseCommand(() => ContractorsViewModel.SendAddress(i.MemberId ));
contractorAddValue.Addresses = new List<Addresses>();
foreach (var a in adressList)
{
Addresses memberAdress = new Addresses();
memberAdress.MemberAddress = a;
memberAdress.EditAddress = new BaseCommand(() => ContractorsViewModel.SendEditAddress(a.MemberAddressId , i.MemberId ));
contractorAddValue.Addresses.Add(memberAdress);
}
listContractorAddValue.Add(contractorAddValue);
}
return listContractorAddValue;
}
allContractors2 - the order by works, but I retrieve repeating Members. In this approach I tried to use .Distinct() after Select(c => c.Member) but it doesn't work (the whole query stops working).
My goal is to make an order by MemberAddress.City
Thanks in advance!
I think that this code will work but you need to redefine the Equals method of the ContractorAddValue class.
I added one if statement when you want to add contractorAddValue to the list. First you need to check if your list contains that object. If not you add the object to the list. If yes you need to find that object and merge its addresses list with addresses list from the object you want to add.
public ObservableCollection<ContractorAddValue> GetContractorsOrderByCity()
{
var allContractors = (from c in db.Member where c.IsContrator == true select c).ToList();
//var allContractors2 = db.Member .Include(c => c.MemberAddress).SelectMany(c => c.MemberAddress).OrderBy(c => c.City).Select(c => c.Member ).ToList();
//var allContractors = (from c in db.Member where c.IsContrator == true select c).OrderBy(c => c.MemberAddress.OrderBy(x => x.City)).ToList(); <= dosent work
var listContractorAddValue = new ObservableCollection<ContractorAddValue>();
foreach (var i in allContractors)
{
var adressList = db.MemberAddress.Where(x => x.MemberId == i.MemberId).OrderBy(x => x.City).ToList();
ContractorAddValue contractorAddValue = new ContractorAddValue();
contractorAddValue.Member = i;
contractorAddValue.AddAddress = new BaseCommand(() => ContractorsViewModel.SendAddress(i.MemberId ));
contractorAddValue.Addresses = new List<Addresses>();
foreach (var a in adressList)
{
Addresses memberAdress = new Addresses();
memberAdress.MemberAddress = a;
memberAdress.EditAddress = new BaseCommand(() => ContractorsViewModel.SendEditAddress(a.MemberAddressId , i.MemberId ));
contractorAddValue.Addresses.Add(memberAdress);
}
if(!listContractorAddValue.Contains(contractorAddValue)){
listContractorAddValue.Add(contractorAddValue);
} else {
var contAddValue = listContractorAddValue.First(l => l.Equals( contractorAddValue));
contAddValue.Addresses.AddRange(contractorAddValue.Addresses);
}
}
return listContractorAddValue;
}

Join (Include) Between Model and AspNetUsers

Several time, i need to get the name of user in AplicationUsers (aspnetusers). Like in Chamado model (table) i have a column Id_Agente (user). With a simple List, i will get something like:
"3q0aju9-9ijuso-9sodkci..."
public class Chamado
{
public int Id { get; set; }
public DateTime Abertura { get; set; }
public string Titulo { get; set; }
public string Descricao { get; set; }
public string Id_Agente { get; set; }
[NotMapped]
public String NomeAgente { get; set; }
}
To work around, I created a NotMapped field and filled it with a foreach:
using (IdentityContext id2 = new IdentityContext())
{
foreach (var item in historicos)
{
item.NomeAgente = id2.Users
.Where(u => u.Id == item.Id_Agente)
.Select(u => u.Nome).FirstOrDefault();
}
}
But now I need to group Chamados by Agente, and it's becoming more and more harder, to work around. I tried to make another notMapped on chamados model named Qtde, make a list and extract from that list but returned a error:
public List<PainelChamados> ListarOrdem()
{
using (SistemaContext db = new SistemaContext())
{
var chamados = db.Chamado
.Where(c => c.Situacao != Chamado.Esituacao.Concluido)
.GroupBy(c => c.Id_Agente)
.Select(c => new Chamado { Id_Agente = c.Key, Qtde = c.Count() });
using (IdentityContext id2 = new IdentityContext())
{
foreach (var item in chamados)
{
item.NomeAgente = id2.Users
.Where(u => u.Id == item.Id_Agente)
.Select(u => u.Nome).FirstOrDefault();
}
}
var query = chamados
.Select(c => new PainelChamados
{
Agente = c.NomeAgente,
Qtde = c.Qtde
});
return query.ToList();
}
}
Last, but not least, how could I just Include aspnetusers table like another regular table:
var query = db.Suporte_Projeto
.Include(l => l.Licenciado)
.Include(c => c.Condominio)
.Include(pr => pr.ProjetoProduto)
.Include(p => p.ProjetoAcesso);
Chart Data
Error
I did another work around! It's seems to be a good option while i cant join aspnetusers to my models table:
public List<PainelChamados> ListarOrdem()
{
using (SistemaContext db = new SistemaContext())
{
var query = db.Chamado
.Where(c => (c.Situacao != Chamado.Esituacao.Concluido && c.Id_Agente != null))
.GroupBy(e => new { e.Id_Agente})
.Select(lg => new PainelChamados
{
CodAgente = lg.Key.Id_Agente,
Qtde = lg.Count()
});
UsuarioData ud = new UsuarioData();
List<PainelChamados> Lista = new List<PainelChamados>();
foreach (var item in query)
{
Lista.Add(new PainelChamados
{
CodAgente = item.CodAgente,
Agente = item.CodAgente == null ? string.Empty : ud.GetAgenteId(item.CodAgente),
Qtde = item.Qtde
});
}
return Lista;
}
}
What do you think, is it the best way to work around? I could return the list i desired.
Chart With Agente Names

Building up a where filter from a message based request

I have a small request object to filter by.
public class BufferFlatViewFilter
{
public bool? Active { get; set; }
public int? CustomerId { get; set; }
public int? TypeId { get; set; }
}
And I need to build up the where filter for the db request.
With Entity framework I was able to build up the Where Statement like so.
public List<BufferFlatView> GetBufferFlatView(BufferFlatViewFilter filter)
{
var data = db.qryCampaignOverView
.AsQueryable();
if (filter.TypeId.HasValue)
data = data.Where(x => x.TypeId == filter.TypeId.Value);
if (filter.CustomerId.HasValue)
data = data.Where(x => x.CustomerId == filter.CustomerId);
if (filter.Active)
data = data.Where(x => x.Active == filter.Active);
return data.ToList();
}
I'm not sure of how to build up the where statement for OrmLight given that Entity framework query is lazy loaded but not the OrmLight query.
We recently added expression chaining in the OrmLite ExpressionVisitor - code copy & pasted from the unit tests:
var visitor = dbConnection.CreateExpression<Person>();
visitor.Where(x => x.FirstName.StartsWith("Jim")).And(x => x.LastName.StartsWith("Hen"));
var results = db.Select<Person>(visitor);
Assert.AreEqual(1,results.Count);
visitor.Where(x => x.Age < 30).Or(x => x.Age > 45);
results = db.Select<Person>(visitor);
Assert.AreEqual(5, results.Count);
Assert.IsFalse(results.Any(x => x.FirstName == "Elvis"));
Note: Where(x => predicate) and .And(x => predicate) are functionally the same.
You can also build up your Order By expression
visitor.OrderBy(x => x.Name).ThenByDescending(x => x.Age);
So your code becomes
public List<BufferFlatView> GetBufferFlatView(BufferFlatViewFilter filter)
{
//assumes IDbConnection instance injected by IOC
var ev = dbConnection.CreateExpression<Campaign>();
if (filter.TypeId.HasValue)
ev.Where(x => x.TypeId == filter.TypeId.Value);
if (filter.CustomerId.HasValue)
ev.Where(x => x.CustomerId == filter.CustomerId);
if (filter.Active)
ev.Where(x => x.Active == filter.Active);
return dbConnection.Select<Campaign>(ev);
}
you could do something like this.
public class Poco
{
public int TypeId { get; set; }
public int CustomerId { get; set; }
public bool Active { get; set; }
}
public class Filter<T>
{
private List<Func<T, bool>> filters = new List<Func<T, bool>>();
public void AddFilter(Func<T, bool> filter)
{
this.filters.Add(filter);
}
public bool PredicateFilter(T item)
{
return filters.All(x => x(item));
}
}
static void Main(string[] args)
{
var list = new List<Poco>() { new Poco { Active = true, CustomerId = 1, TypeId = 1 } };
var filter = new Filter<Poco>();
filter.AddFilter(x => x.Active == false);
filter.AddFilter(x => x.CustomerId == 1);
filter.AddFilter(x => x.TypeId == 1);
var item = list.Where(x => filter.PredicateFilter(x));
Console.Read();
}

Categories