QueryOver Criteria with Contains - fluent-nhibernate

I am trying to get if list of subclass contains a match. I am new at NHibernate and looking for help.
thank you
public class Shop
{
public virtual int ShopId { get; set; }
public virtual string ShopName { get; set; }
public virtual IList<DeliveryDistrict> DeliveryDistricts { get; set; }
}
public class DeliveryDistrict
{
public virtual int DeliveryDistrictId { get; set; }
public virtual Location.District District { get; set; }
}
public class District
{
public virtual int DistrictId { get; set; }
public virtual string DistrictName { get; set; }
}
stores = session.QueryOver<Entities.Shop.Shop>()
.Where(f => f.DeliveryDistricts.Contains(District)).ToList();
stores = session.QueryOver<Entities.Shop.Shop>()
.Where(p => p.DeliveryDistricts.Any(c => c.District.DistrictId == District.DistrictId)).List();

I could make it work with Query(Linq) like this;
stores = session.Query<Entities.Shop.Shop>()
.Where(p => p.DeliveryDistricts.Any(c => c.District.DistrictId == District.DistrictId)).ToList();
but I would like to see if anyone has an example on QueryOver

Related

How can I Get the results of the nested query in the form of entities with EF

I have some models in my project:
**Model ServiceDeliveryDoc**
public string Id { get; set; }
public string PartnerDocId { get; set; }
public DateTime Date { get; set; }
public decimal Cost { get; set; }
public string LegalEntityId { get; set; }
[ForeignKey("LegalEntityId")]
[InverseProperty("ServiceDeliveryDoc")]
public LegalEntity LegalEntity { get; set; }
[InverseProperty("ServiceDeliveryDoc")]
public ICollection<ServiceRegistryToServiceDeliveryDoc> ServiceRegistryToServiceDeliveryDoc { get; set; }
**Model ServiceRegistry**
public string Id { get; set; }
public DateTimeOffset Date { get; set; }
public decimal Cost { get; set; }
[InverseProperty("ServiceRegistry")]
public ICollection<ServiceRegistryToServiceDeliveryDoc> ServiceRegistryToServiceDeliveryDoc { get; set; }
**Model ServiceRegistryToServiceDeliveryDoc**
public string Id { get; set; }
public string ServiceRegistryId { get; set; }
public string ServiceDeliveryDocId { get; set; }
[ForeignKey("ServiceDeliveryDocId")]
[InverseProperty("ServiceRegistryToServiceDeliveryDoc")]
public ServiceDeliveryDoc ServiceDeliveryDoc { get; set; }
[ForeignKey("ServiceRegistryId")]
[InverseProperty("ServiceRegistryToServiceDeliveryDoc")]
public ServiceRegistry ServiceRegistry { get; set; }
I write some nested query in SQL to get ServiceDeliveryDoc with
LegalEntity, filtered by ServiceRegistryId:
SELECT ReturnsTable.[Id]
,ReturnsTable.[PartnerDocId]
,ReturnsTable.[Date]
,ReturnsTable.[Cost]
,ReturnsTable.[LegalEntityId]
,LegalEntityTable.[Name]
,ReturnsTable.[DocProcessId]
FROM [Vishnya].[dbo].[ServiceDeliveryDoc] as ReturnsTable
left join [Vishnya].[dbo].[LegalEntity] as LegalEntityTable
on ReturnsTable.[LegalEntityId] = LegalEntityTable.[Id]
where ReturnsTable.Id in ( select ServiceDeliveryDocId
from ServiceRegistry_To_ServiceDeliveryDoc
where ServiceRegistryId = #ServiceRegistryId)
How I can recieve simular result, using Enity framework?
From your SQL query and the model design , there is a one-to-one relationship between ServiceDeliveryDoc and LegalEntity , many-to-many relationship between ServiceDeliveryDoc and ServiceRegistry . For loading related data , you could use include like below:
var result = _context.ServiceDeliveryDoc
.Include(sd => sd.LegalEntity)
.Where(sd =>
_context.ServiceRegistryToServiceDeliveryDoc
.Where(srt => srt.ServiceRegistryId == "101")
.Select(srt => srt.ServiceDeliveryDocId)
.Contains(sd.Id)
)
.Select(sd => new
{
sd.Id,sd.PartnerDocId , sd.Date,sd.Cost,sd.LegalEntityId, sd.LegalEntity.Name
}).ToList();
DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<ServiceRegistryToServiceDeliveryDoc>()
.HasOne(sr => sr.ServiceDeliveryDoc)
.WithMany(sd => sd.ServiceRegistryToServiceDeliveryDoc)
.HasForeignKey(sr => sr.ServiceDeliveryDocId);
modelBuilder.Entity<ServiceRegistryToServiceDeliveryDoc>()
.HasOne(sr => sr.ServiceRegistry)
.WithMany(sd => sd.ServiceRegistryToServiceDeliveryDoc)
.HasForeignKey(sr => sr.ServiceRegistryId);
}

Linq with EF, include specific columns

I have two classes:
public class Category
{
public int Id { get; set; }
[Required]
[MaxLength(255)]
public string Name { get; set; }
public int? CategoryId { get; set; }
public double Weight { get; set; }
public ICollection<Article> Articles { get; set; }
public bool Hidden { get; set; }
}
public class Article
{
public int Id { get; set; }
[StringLength(255)]
public string Title { get; set; }
public string Body { get; set; }
public double Weight { get; set; }
public Category Category { get; set; }
public int? CategoryId { get; set; }
}
I would like to select some Categories including Articles, but without Article.Body. Method syntax is more preferred.
Something like:
IEnumerable<Category> categories = _context
.Categories
.Where(c => c.Hidden == false)
.Include(c => c.Articles)
.OrderBy(c => c.Weight);
Not sure how to specify which columns exactly to select (eagerly) on the included Articles.
Include doesn't allow projections, you can only include complete entities.
But there is a way out.
This is a typical case that you should solve by table splitting. By table splitting you "split" a table over two (or more) entities, so it's easier to filter e.g. light data from heavy data or public data from secure data.
In your case the class model (for Article) would look like this:
public class Article
{
public int Id { get; set; }
[StringLength(255)]
public string Title { get; set; }
public double Weight { get; set; }
public Category Category { get; set; }
public int? CategoryId { get; set; }
public virtual ArticleBody ArticleBody { get; set; }
}
public class ArticleBody
{
public int Id { get; set; }
public string Text { get; set; }
}
And the mappings:
modelBuilder.Entity<Article>()
.HasRequired(a => a.ArticleBody)
.WithRequiredPrincipal();
modelBuilder.Entity<Client>().ToTable("Article");
modelBuilder.Entity<ArticleBody>().ToTable("Article");
Now if you do...
_context.Categories
.Where(c => !c.Hidden)
.Include(c => c.Articles)
...you'll see that only Articles without body texts will be selected in the generated SQL.
If you want the body as well, you do
_context.Categories
.Where(c => !c.Hidden)
.Include(c => c.Articles.Select(a => a.ArticleBody))
Sorry if i did not understand your question, but I think you can specify what columns you want in your select statement.
Simple example:
var query = from c in Categories
select c.Name, c.CategoryId;

Parent Child Relationship in ASP.NET MVC 4

I am trying to do this:
Hibernate: Parent-Child Relationship to Itself
but in ASP.NET MVC 4
here are my 2 models (which i have no clue if this is the correct way to do this):
public class Group
{
public int GroupID { get; set; }
[Required]
[StringLength(50)]
public string Name { get; set; }
public virtual ICollection<GroupRelation> GroupRelations { get; set; }
}
public class GroupRelation
{
public int GroupRelationID { get; set; }
public int? ParentID { get; set; }
public int? ChildID { get; set; }
[ForeignKey("ParentID")]
public virtual Group ParentGroups { get; set; }
[ForeignKey("ChildID")]
public virtual Group ChildGroups { get; set; }
}
Here is my Context(again no clue if this is right):
public class TaskTrackerContext : DbContext
{
public DbSet<Group> Groups { get; set; }
public DbSet<GroupRelation> GroupRelations { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Group>()
.HasMany(g => g.GroupRelations).WithOptional(g => g.ChildGroups).HasForeignKey(g => g.ChildID);
modelBuilder.Entity<Group>()
.HasMany(g => g.GroupRelations).WithOptional(g => g.ParentGroups).HasForeignKey(g => g.ParentID);
}
}
With this setup i get the following in my database:
(i tried to put in a pic or a link to a pic and it wont let me...)
So it makes the 2 relationships i am expecting "PK_GroupID - FK_ParentID" and "PK_GroupID - FK_ChildID", but then it creates an extra column called "Group_GroupID" and makes the following relationship: "PK_GroupID - FK_Group_GroupID".
So what am I doing wrong?

fluent nhibernate mapping issue

I have two objects Customer_policy and policy_maturity.
public class Customer_policy
{
public virtual String policy_no { get; set; }
public virtual DateTime maturity_date { get; set; }
public virtual Boolean matured_status { get; set; }
}
public class Policy_maturity
{
public virtual string policy_no { get; set; }
public virtual string customer_id { get; set; }
public virtual float maturity_amt { get; set; }
public virtual string policy_type { get; set; }
public virtual DateTime pay_date { get; set; }
}
When a customer creates a policy Customer_policy is getting populated but Policy_maturity should remain empty(which I have already done). When a policy matures I want to insert a row in Policy_maturity and update matured_status field of the corresponding Customer_policy. What type of mapping should I do so that inserting and update gets accomplished by hitting the database only one time ??? Thanx for your suggestions.
a suggestion:
public class CustomerPolicy
{
public virtual String PolicyNumber { get; private set; }
public virtual DateTime MaturityDate { get; set; }
public virtual PolicyMaturity Maturity { get; private set; }
public virtual Boolean HasMatured { get { return Maturity != null; } }
public virtual void DoMature(Customer customer, float maturity_amt, string policyType, DateTime payDate)
{
DoMature(new PolicyMaturity
{
Customer = customer,
MaturityAmt = maturity_amt,
PolicyType = policyType,
PayDate = payDate,
});
}
/*public*/ virtual void DoMature(PolicyMaturity maturity)
{
Maturity = maturity;
MaturityDate = DateTime.Today;
}
}
public class PolicyMaturity
{
public virtual String PolicyNumber { get; private set; }
public virtual CustomerPolicy Policy { get; set; }
public virtual Customer Customer { get; set; }
public virtual float MaturityAmt { get; set; }
public virtual string PolicyType { get; set; }
public virtual DateTime PayDate { get; set; }
}
class CustomerPolicyMap : ClassMap<CustomerPolicy>
{
public CustomerPolicyMap()
{
Id(cp => cp.PolicyNumber).GeneratedBy.Assigned();
Map(cp => cp.MaturityDate);
HasOne(cp => cp.Maturity);
}
}
class PolicyMaturityMap : ClassMap<PolicyMaturity>
{
public PolicyMaturityMap()
{
Id(cp => cp.PolicyNumber).GeneratedBy.Foreign("Policy");
HasOne(cp => cp.Policy);
References(cp => cp.Customer);
Map(cp => cp.MaturityAmt);
Map(cp => cp.PayDate);
Map(cp => cp.PolicyType);
}
}
then if you save the Updated Customerpolicy NHibernate should batch the two updates
You will need to ask NHibernate to batch the two DML queries. Have a look at this blog post for a detailed description of how to use batching in NHibernate.
Wrapping the two operations in a transaction (as the example in the blog post does) is also a good idea.

Column Property AutoMapping

There is o possibility to create a convention for Column naming:
I have this piece of code:
public AutoPersistenceModel Generate()
{
var result = AutoPersistenceModel.MapEntitiesFromAssemblyOf<User>()
.Where(GetAutoMappingFilter)
.WithConvention(GetConventions);
return result;
}
private bool GetAutoMappingFilter(Type t)
{
return
t.GetInterfaces().Any(
x => x.IsGenericType && (x.GetGenericTypeDefinition() == typeof(IEntityWithTypedId<>)));
}
private static void GetConventions(Conventions conventions)
{
conventions.GetPrimaryKeyNameFromType = type => type.Name.ToLower() + "_id";
conventions.FindIdentity = type => type.Name.ToLower() == "id";
conventions.GetTableName = type =>
{
if (!type.Name.Contains("Lookup"))
{
return Inflector.Net.Inflector.Pluralize(type.Name).ToLower();
}
return Inflector.Net.Inflector.Underscore(type.Name)
.Replace("lookup", "lu").ToLower();
};
conventions.IsBaseType = DontMapAsJoinedSubclassTypesInheritedFrom;
conventions.GetForeignKeyNameOfParent = type => Inflector.Net.Inflector.Underscore(type.Name) + "_id";
conventions.GetForeignKeyName = type => Inflector.Net.Inflector.Underscore(type.Name) + "_id";
conventions.OneToManyConvention = m => m.Cascade.All();
}
private static bool DontMapAsJoinedSubclassTypesInheritedFrom(Type arg)
{
var derivesFromEntity = arg == typeof(Entity);
var derivesFromEntityWithTypedId = arg.IsGenericType &&
(arg.GetGenericTypeDefinition() == typeof(EntityWithTypedId<>));
return derivesFromEntity || derivesFromEntityWithTypedId;
}
and an Entity class
public class Organisation : EntityWithTypedId<int>
{
public virtual Organisation Parent { get; set; }
public virtual LookOrganisationType OrganisationType { get; set; }
[DomainSignature]
public virtual string OrganisationName { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string Postcode { get; set; }
public virtual LookupCountry Country { get; set; }
public virtual string TelNo { get; set; }
public virtual string FaxNo { get; set; }
public virtual string Email { get; set; }
public virtual User Contact { get; set; }
public virtual DateTime? DateCreated { get; set; }
public virtual DateTime? DateAmended { get; set; }
public virtual bool Active { get; set; }
}
Finally I want to have a column for, let's say TelNo like tel_no.
So the Convention is if Property contains capital letter in the middle ti should be underscored. Inflector.Net.Inflector.Underscore works fine. But I do not know how to write the convention.
Somethig like:
(conventions.GetPropertyName = type => Inflector.Net.Inflector.Underscore(type.ColumnName))
Thanks