c# return named tuple from linq join - c#

i'am trying to perform a join between a revision entity from nhibernate envers and a list with user names. i want to return a list of named tuples.
this is my code
public IEnumerable<(Societa company, DateTime datetime, string userName)> CompanyHistory()
{
IAuditReader auditReader = this._session.Auditer();
var revison = auditReader.CreateQuery().ForHistoryOf<Societa, RevisionEntity>().Results();
IList<Persona> user = _session.QueryOver<Persona>().List();
var query = revison.Join(user,
rev => rev.RevisionEntity.IdUtente,
us => us.Id,
(rev, us) => new
{
Oggetto = rev.RevisionEntity,
DataModifica = rev.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente = us.NomePersona
}).ToList();
}
but now i didn't find a way to return the tuple
cast didn't work
ToValueTuple is not avaible to fro my query object
i try also
(ele, p) => new (OutputGA Oggetto, DateTime DataModifica, string NomeUtente)
{
Oggetto = ele.RevisionEntity,
DataModifica = ele.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente = p.NomePersona
}).ToList();
but i got new cannot be used with tuple type
than
(ele, p) => new Tuple<OutputGA, DateTime, string>
{
Oggetto = ele.RevisionEntity,
DataModifica = ele.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente = p.NomePersona
}).ToList();
and got error about parameter not corresponding

You can try this
var tuples = data.Select(x => (A: x.A, B: x.B));

I think the correct syntax should be
(ele, p) =>
(
Oggetto: ele.RevisionEntity,
DataModifica: ele.RevisionEntity.RevisionDate.ToLocalTime(),
NomeUtente: p.NomePersona
)).ToList();

Related

C# Linq query to return Dictionary<int,int[]>

Ok, so I have a need to create/return a Dictionary from the results of a Linq Query. I have tried just about everything I can think of and keep running into issues. Here is what I am currently attempting...
public static Dictionary<int,int[]> GetEntityAuthorizations(int userId)
{
using (MyDb db = new MyDb())
{
var query = db.EntityManagerRoleAssignments.Where(x => x.EntityManager.ManagerId == userId);
var entityId = query.Select(x => x.EntityManager.EntityId);
var roles = query.Select(x => x.RoleId).ToArray();
var result = query.ToDictionary(entityId, roles);
return result;
}
}
any help at all would be greatly appreciated. what i am looking for to be returned from this is a Dictionary where the Key is the entityId or EntityManager.EntityId and the Value(s) are an array of associated RoleId's.
Currently I am getting the following two errors at compile time, and other attempts have been errors similar but not exact to these.
Error 11 The type arguments for method 'System.Linq.Enumerable.ToDictionary<TSource,TKey>(System.Collections.Generic.IEnumerable, System.Func<TSource,TKey>, System.Collections.Generic.IEqualityComparer<TKey>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Error 12 Cannot implicitly convert type 'System.Collections.Generic.Dictionary<TKey,Sqor.Database.DbEntityManagerRoleAssignment>' to 'System.Collections.Generic.Dictionary<int,int[]>'
UPDATE - Working Solution (Thanks to #D Stanley)
public static Dictionary<int,int[]> GetEntityAuthorizations(int userId)
{
using (SqorDb db = new SqorDb())
{
var query = db.EntityManagerRoleAssignments.Where(x => x.EntityManager.ManagerId == userId);
var entityGroups = query.GroupBy(x => x.EntityManager.EntityId);
var result = entityGroups.ToDictionary(e => e.Key,
g => g.Select(x => x.RoleId).ToArray()
);
return result;
}
}
It sounds like you want to group by the Entity ID and project the associated role IDs to an array:
using (MyDb db = new MyDb())
{
var query = db.EntityManagerRoleAssignments.Where(x => x.EntityManager.ManagerId == userId);
var entityGroups = query.GroupBy(x => x.EntityManager.EntityId);
var result = entityGroups.ToDictionary(e => e.Key,
g => g.Select(x => x.RoleId).ToArray()
);
return result;
}

EF error Unable to create a constant value of type 'Anonymous type'. Only primitive types or enumeration types are supported in this context

I m querying some collections and then converting my result to JSON but getting below error:
Unable to create a constant value of type 'Anonymous type'. Only
primitive types or enumeration types are supported in this context
Below is my code, please guide & help me.
var AllStatus = RepositoryFactory.OrderStatusRepository.GetAll().AsEnumerable().Select(s => new
{
Status = s.Status,
StatusId= s.Id
});
var AllUsers = RepositoryFactory.UserRepository.GetAll().AsEnumerable().Select(u => new
{
UserId= u.UserId,UserName=u.UserName
});
var result = RepositoryFactory.OrderHistoryRepository.GetAll().Select(v => new
{
PatientId = v.UserId ,
UserName = AllUsers.Where(u=>u.UserId==v.UserId).Select(u=>u.UserName),
Status = AllStatus.Where(s=>s.StatusId==v.OrderStatusId).Select(s=>s.Status),
StatusDate = v.UpdatedDate,
Amount = v.Amount
}) ;
returnModel.Data = result.ToJSON();
thanks
Parts of code: AllUsers.Where(u=>u.UserId==v.UserId).Select(u=>u.UserName) and AllStatus.Where(s=>s.StatusId==v.OrderStatusId).Select(s=>s.Status) return IEnumerable<string>, and you need, I guess, single string;
Instead Select method, use ToDictionary
var AllStatus = RepositoryFactory.OrderStatusRepository.GetAll().AsEnumerable()
.ToDictionary(x=> x.Id, x=> x.Status);
var AllUsers = RepositoryFactory.UserRepository.GetAll().AsEnumerable()
.ToDictionary(u => u.UserId, u=> u.UserName);
var result = RepositoryFactory.OrderHistoryRepository.GetAll()
.Select(v => new
{
PatientId = v.UserId ,
UserName = AllUsers.ContainsKey(v.UserId) ? AllUsers[v.UserId] : null,
Status = AllStatus.ContainsKey(v.StatusId) ? AllUsers[v.StatusId] : null,
StatusDate = v.UpdatedDate,
Amount = v.Amount
}) ;

expression cannot be translate into store expression

I have to download some complex datas from database which aggregate lots of usefull infos about post. I would like to do something like this:
var list = (from message in db.BLOGS_MESSAGES
where message.BLOG_ID == blogId
orderby message.CREATED_DATE descending
select new BlogMessage()
{
AUTHORS = **(from author in message.AUTHORS
select author.USERS).ToArray()**,
CREATED_BY = message.CREATED_BY,
CREATED_DATE = message.CREATED_DATE,
BLOG_MESSAGE_ID = message.POST_ID,
MESSAGE_TITLE = message.TITLES.TITLE,
TAGS = **(from tag in message.TAGGED_MESSAGES
select tag.TAGS).ToArray()**,
LOGIN = message.USERS.LOGIN,
MESSAGE = message.MESSAGES.MESSAGE,
MESSAGE_ID = message.MESSAGE_ID,
POST_NOTE = message.POST_NOTES.Sum(x => (long?)x.NOTE) ?? 0 / message.POST_NOTES.Count(),
}).ToList();
but it doesn't work. It throws an exception that can't translate expression in store expression.
so far i did it in this way:
var mlist = (from message in db.BLOGS_MESSAGES
where ....
orderby ....
select new {
AUTHORS = (from author in message.AUTHORS
select author.USERS),
....
}
List<BlogMessage> list = new List<BlogMessage>();
foreach(var item in mlist)
{
list.Add(new BlogMessage()
{
AUTHORS = item.AUTHORS.ToArray(),
...
});
}
is it possible to make it work 'in first way - style'?
You can either:
Change BlogMessage.AUTHORS to be an IEnumerable<USERS> and remove the .ToArray() calls in the query like Grundy suggested.
Bring the results into memory before creating BlogMessage's.
For example:
var step1 = db.BLOGS_MESSAGES
.Where(...)
.Select(message => new {
Authors = message.AUTHORS.Select(a => a.USERS), // No .ToArray()
...
}).ToList();
var step2 = step1.Select(message => New BlogMessage {
Authors = message.Authors.ToArray(),
...
}).ToList();

MySql Linq to SQL conver int to string

Hello I have a MySQL and LINQ to SQL task to convert Int value from DB to String,
toString() is not supported by MySql, and I am getting error about it.
var data = (from o in ObjectContext.MyTable.Where(d => d.a == a)
select new MyObject
{
Id = o.Id,
StringProperty = o.intColumn.ToString()
});
SqlFunction class is not suported for MySql.
You can try to convert the results to Enumerable and then query on it:
var data = (from o in ObjectContext.MyTable.Where(d => d.a == a)
select new MyObject
{
Id = o.Id,
StringProperty = o.intColumn.ToString()
}).AsEnumerable();
You could fetch all the data by adding AsEnumerable() to the table, or you could do the fetch first, then the conversion later - if I'm not mistaken, this should produce a slightly lighter SQL call:
var tempData = (from o in ObjectContext.Where(d => d.a == a) select o);
var converted = (from o in tempData.AsEnumerable()
select new MyObject
{
Id = o.Id,
StringProperty = o.intColumn.ToString()
});
Alternatively, write it all in one go by using the first part as a sub query:
var data = from x in
(from o in ObjectContext.Where(d => d.a == a) select o)
.AsEnumerable()
select new MyObject
{
Id = x.Id,
StringProperty = x.intColumn.ToString()
});
int to string in Entity Framework
also had supported a great solution you can refer. By this method you can change you source as the following.
var data = (from o in ObjectContext.MyTable.Where(d => d.a == a)
select new MyObject
{
Id = o.Id,
StringProperty = SqlFunctions.StringConvert((double)o.intColumn)
});

MongoDB select row by id and get fields (in c#) [duplicate]

first time i'm using MongoDB.
I have read this example:
SELECT a,b FROM users WHERE age=33
db.users.find({age:33}, {a:1,b:1})
But I can't translate it into C#. Can anyone help me?
I have translated your query below using the new C# driver (2.2)
var mongoClient = new MongoClient(""mongodb://127.0.0.1:27017"");
var database = mongoClient.GetDatabase("databaseName");
IMongoCollection<Users> _collection = database.GetCollection<Users>("Users");
var condition = Builders<Users>.Filter.Eq(p => p.age, 33);
var fields = Builders<Users>.Projection.Include(p => p.a).Include(p => p.b);
var results= _collection.Find(condition).Project<Users>(fields).ToList().AsQueryable();
You can do it using SetFields method of MongoCursor class, below full example:
var server = MongoServer.Create(connectionString);
var db = _server.GetDatabase("dbName");
var users = db.GetCollection("users");
var cursor = users.FindAs<DocType>(Query.EQ("age", 33));
cursor.SetFields(Fields.Include("a", "b"));
var items = cursor.ToList();
you can use anonymous class
public class User
{
public int age;
public string a;
public string b;
}
var collection = db.GetCollection<User>("Users");
var results = collection.Find(Builders<User>.Filter.Eq(user => user.age, 33))
.Project(u => new { u.a, u.b }).ToList();
//create user class
//(not sure how your class looks like)
public class User
{
public int age;
public string a;
public string b;
}
//then you can use LINQ easily
var server = MongoServer.Create(connectionString);
var db = server.GetDatabase("dbName");
var usersCollection = db.GetCollection<User>("users");
var filteredCollection = usersCollection.AsQueryable().Where(x=> x.age < 33).Where(x=> x.a != null).Contains(x=> x.b != null);

Categories