Nhibernate query to get the quantity count joining tables - nhibernate

I need an nhibernate query to get the quantity count .
here's my entities. I have a master Inventory table and a Used Inventory table.
public Inventory
{
Id,
Name,
Type,
...
}
public UsedInventory
{
Id,
Inventory,
Quantity,
Date,
..
}
I am looking for output that look like:
public ResultDTO
{
Inventory,
TotalUsedQuantity
}
please help.
Thanks

In LINQ, it is easy:
session.Query<UsedInventory>().GroupBy(x => x.Inventory).Select(x => new ResultDTO { Inventory = x.Key, TotalUsedQuantity = x.Count() }).ToList();

In QueryOver:
ResultDTO dto = null;
var rrr = session.QueryOver<UsedInventory>().SelectList(list => list
.SelectGroup(m => m.Inventory).WithAlias(() => dto.Inventory)
.SelectCount(m => m.Id).WithAlias(() => dto.TotalUsedQuantity)).List<ResultDTO>();

Related

Get data from database with where clause using API

I have a table named SerialNumbers containing some columns in it.
I want to get the data with SNum based on scanned value which has been listed in an Array.
Below is my code:
public class SNController : ApiController
{
[HttpGet]
public HttpResponseMessage AllSN()
{
using (SNDBContext dbContext = new SNDBContext())
{
string[] SNum = { "01070A2", "01070A3", "01070A4" };
var SerialNum = dbContext.SNumbers.Where(x => x.SN == "01070A2")
.Select(p => new { p.Name, p.Status})
.ToList();
return Request.CreateResponse(HttpStatusCode.OK, SerialNum );
}
}
When I try to hardcoded this part var SerialNum = dbContext.SNumbers.Where(x => x.SN == "01070A2"), its working.
How can I solve this issue?
Use Contains method in Where clause.
var SerialNum = dbContext.SNumbers.Where(x => SNum.Contains(x.SN))
.Select(p => new { p.Name, p.Status})
.ToList();

How can I select the root entity and child entity count using QueryOver in NHibernate?

I have a pretty simple query I'm trying to convert to NHibernate's QueryOver syntax, but I'm having difficulty. The original SQL query is functionally the same as:
SELECT [Post].*, (
SELECT Count(*)
FROM [Comment]
WHERE [Comment].[PostId] = [Post].[Id]) AS [CommentCount]
FROM [Post]
The problem is I'm having difficulty converting this to QueryOver syntax. I tried defining a summary class containing both the Post and the CommandCount as such:
public class PostSummary
{
public Post Post { get; set; }
public CommentCount { get; set; }
}
And then defining the query with a couple of selects:
Post lPostAlias = null;
Comment lCommentAlias = null;
var lCommentSubquery = QueryOver.Of(() => lCommentAlias)
.Where(() => lCommentAlias.Post.Id == lPostAlias.Id)
.ToRowCountQuery();
PostSummary lPostSummaryAlias = null;
session.QueryOver(() => lPostAlias)
.SelectList(list => list
.Select(x => x).WithAlias(() => lSummary.Post)
.SelectSubQuery(lCommentSubQuery).WithAlias(() => lSummary.CommentCount)
.List<PostSummary>();
An exception gets thrown with the error message:
could not resolve property: of: Project.Models.Post
So it looks like it doesn't like the .Select(x => x) part of the query. I was hoping to find something along the lines of 'Projections.RootEntity()` but alas there is no such thing that I can find.
Can someone explain what I'm doing wrong and guide me to the proper way to do this basic query? I imaging I could select all the properties of Post that I want, but worry that I'll lose the ability to take advantage of the proxy sub-classes NHibernate generates for lazy-loading purposes and is not what I want.
using the LINQ provider you can write
var query = from post in session.Query<Post>()
select new PostSummary { Post = post, CommentCount = post.Comments.Count };
return query.ToList();

RavenDB Index is not working when using SelectMany in Map Function

Based on this article from Ayende i have created the following index definition
public class ProductsSearch : AbstractIndexCreationTask<Product, ProductsSearch.Result>
{
public class Result
{
public string Query { get; set; }
}
public ProductsSearch()
{
Map = products => from product in products
select new
{
Query = new object[]
{
product.Title,
product.Tags.Select(tag => tag.Name),
product.Tags.SelectMany(tag => tag.Aliases, (tag, alias) => alias.Name)
}
};
Index(x => x.Query, FieldIndexing.Analyzed);
}
}
One difference is that i must use a SelectMany statement to get the aliases of a tag.
A tag can have many aliases (i. e. tag: mouse alias:pointing device)
I have no idea why the SelectMany line breaks the index. If i remove it, the index works.
This should work:
Map = products => from product in products
from tag in product.Tags
from alias in tag.Aliases
select new
{
Query = new object[]
{
product.Title,
tag.Name,
alias.Name
}
};

How to Fluently map with constraint in HasMany

I’m new to (fluent) nHibernate.
I have 3 tables:
Agency
• AgencyId (pk)
• AgencyAccountNo
AgencyAccount
• AgencyId (pk) (fk -> Agency. AgencyId)
• AgencyAccountNo (pk)
• ChainId (fk -> AgencyChain.ChainId)
AgencyChain
• ChainId (pk)
AgencyAccount is effectively a versioning table. Everytime an Agency changes a new AgencyAccount row with an incremented AgencyAccountNo.
I am trying to fluently map the relationships in Agency and AgencyChain so that only the Current AgencyAccount will be returned, but have had a lot of trouble. I have tried many, many things, too numerous to go into here, and can’t seem to find any examples or documentation on this.
What would your approach be?
the normal/easy way Updated
class AgencyMap : ClassMap<Agency>
{
public AgencyMap()
{
Id(a => a.Id);
Map(a => a.AccountNo);
}
}
class AgencyAccountMap : ClassMap<AgencyAccount>
{
public AgencyAccountMap()
{
CompositeId()
.KeyReference(aa => aa.Agency, "AgencyId")
.KeyProperty(aa => aa.AccountNo, "AgencyAccountNo");
References(a => a.Chain).Column("chainid");
}
}
class AgencyChainMap : ClassMap<AgencyChain>
{
public AgencyChainMap()
{
Id(c => c.Id);
HasMany(c => c.AgencyAccounts)
.KeyColumn("chainid")
// to get only the actual AgencyAccounts
.Where("AgencyAccountNo = (SELECT a.AgencyAccountNo FROM Agency a WHERE a.AgencyId = AgencyId)");
// or if only interested in Agency (using a Set to prevent duplicates coming from the history of agencyaccounts)
HasManyToMany(c => c.Agencys)
.Table("AgencyAccount")
.ParentKeyColumn("chainid")
.ChildKeyColumn("agencyid")
.AsSet();
}
}
var account = session.Get<AgencyAccount>(new AgencyAccount { Agency = agency, AccountNo = agency.AccountNo });
the hackish way when not using Identity but some other id generation
class AgencyMap : ClassMap<Agency>
{
public AgencyMap()
{
Table("AgencyAccount");
Id(a => a.Id, "AgencyId").GeneratedBy.Sequence("agency_id_sequence"); // e.g. sequence
Where("AgencyAccountNo = (SELECT a.AgencyAccountNo FROM Agency a WHERE a.AgencyId = AgencyId)");
Map(a => a.AccountNo);
Join("Agency", join =>
{
join.KeyColumn("AgencyId");
join.Map(<some other prop>);
}
}
}
Note:
this makes inserting new AgencyAccounts for the same Account very difficult
cant show the complete history of AgencyAccounts
possibly has a lot of subtle problems

NHibertnate mapping HasManyToMany results in CROSS JOIN

I'm trying to add a mapping to the table IdentityGroup which has ManyToMany IdentityUsers thought the table IdentityGroupIdentitiy. However when I add the mapping. The result seems to be a something like a cross join.
Expected result for a group with two users:
Group 1:
User 1
User 2
Current result for a group with two users:
Group 1:
User 1
User 2
Group 1:
User 1
User 2
My mapping looks like this:
mapping.HasManyToMany<IdentityUser>(x => x.Users)
.Table("IdentityGroupIdentity")
.ParentKeyColumn("identityGroup_cid")
.ChildKeyColumn("identity_cid");
Code to fetch the data:
public IQueryable<T> Find<T>(params string[] propertiesToLoad)
{
var query = session.Linq<T>();
foreach (var propName in propertiesToLoad)
query.Expand(propName);
if (typeof(T) is ISoftDeletable)
query.Where(x => !(x as ISoftDeletable).IsDeleted);
return query;
}
[...]
public IQueryable<IdentityGroup> Groups
{
get { return Find<IdentityGroup>(new string[] { "DefaultOrganization", "DefaultLocation", "Users" }); }
}
Ant ideas?
Resolved by not "Expanding" the Users-property when fetching...