How to get a single value from db using Fluent Hibernate - asp.net-mvc-4

I'm new to Fluent Hibernate And I'm stuck with a problem I want to get the email id of a user by using his user name means I want to implement the following code using fluent Hibernate
Select emailId from Table where username="User"
I tried the following code but its not give me what i want
public string ForgetPassword(string user)
{
var factory = CreateSessionFactory();
using (var session = factory.OpenSession())
{
var getEmail = session.Query<ClsAccountBL>()
Select(u => u.Email).Where(u => u.User == user).ToString();
return getMail;
}
}
Please help me to solve this

Instead of .ToString() use FirstOrDefault(). The LINQ does not return "single" element.

Related

Fluent NHibernate With Dynamic Table Name

how can I map a dynamic table name to a entity?
Ex, I can have many tables, all have the same structure, however, has its different name, how can I map this using Fluent NHibernate?
remembering that before compiling I do not know the name of these tables.
Can anyone help me?
What you'll probably need to do is put a place holder in the fluent nhibernate mapping for the table name and then replace it after you build the mappings.
Take a look at the following article and I think the first code sample will give you an idea of what you need to do.
http://ayende.com/blog/3294/dynamic-mapping-with-nhibernate
I was able to do this. Here is a rough example:
var fluentConfiguration = Fluently.Configure(NHibernate.Cfg.Configuration().Configure())
.Mappings(m =>
m.FluentMappings
.AddFromAssemblyOf<OrderMap>()
.Conventions.AddFromAssemblyOf<PascalCaseColumnNameConvention>())
.ProxyFactoryFactory("NHibernate.Bytecode.DefaultProxyFactoryFactory, NHibernate");
var config = fluentConfiguration.BuildConfiguration();
foreach(PersistentClass persistentClass in config.ClassMappings)
{
if(persistentClass.MappedClass == typeof(Order))
{
persistentClass.Table.Name = "Dynamic Table";
}
}
//You could substitute above for each loop with linq unless you have a bunch to replace then use foreach
//config.ClassMappings.First(x => x.MappedClass == typeof(Order)).Table.Name = "Dynamic Table";
var sessionFactory = config.BuildSessionFactory();
using(ISession session = sessionFactory.OpenSession())
{
Order order = session.Query<Order>().FirstOrDefault();
}

NHibernate QueryOver (generic), tell query which properties of generic class it should use

it's my first time in NHibernate QueryOver and I'm trying to do it in a generic way.
So far, this is what I have done..
//Find one only
public T Find(string propertyName1, string propertyName2, string value1, string value2)
{
using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
return session.QueryOver<T>().Where(d => propertyName1 == value1)
.And(f => propertyName2 == value2).SingleOrDefault();
}
}
I am not sure if this is right. What I am trying to do is, using a generic class, obtain an object saved in the database using two of its properties.
As you can see, I passed my property1 and property2. Using those two properties, I am wondering if I could query my database to find an object whose properties have the same values as value1 and value2 parameters.
Since it is generic, I need to find a way on how to tell my query which properties it should use as a criteria. What is the correct way to do this? Thanks guys.
Perhaps you should be looking at Criteria Queries instead of QueryOver: http://docs.huihoo.com/hibernate/nhibernate-reference-1.2.0/querycriteria.html
public T Find(string propertyName1, string propertyName2, string value1, string value2)
{
using (var session = sessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
return session.CreateCriteria(typeof(T)).Add(Expression.Eq(propertyName1, value1 ))
.Add(Expression.Eq(propertyName2, value2 )).SingleOrDefault();
}
}

NHibernate CreateSqlQuery() result to an ObservableCollection

I've the following:
using (ISession session = Config.SessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
// This is a System.Collections.ArrayList,contains all my records returned from the session
var list = session.CreateSQLQuery(selectQuery).List();
// I want to put these records in an ObservableCollection of a specific Type
// Something like htis:
MyCollection = new ObservableCollection<MyType>(list);
}
}
This is not working and casting isn't an option here. Is there any way to put my retrurned list to the ObservableCollection?
I've got my ObservableCollection filled by using the following:
var query = session.CreateSQLQuery(selectQuery).AddEntity(typeof(MyType));
myObservableCollection = new ObservableCollection<MyType>(query.List<MyType>());
The List() returns ArrayList. Each value in ArrayList has some value which is type of object.
It can not be converted into directly any specific class. so create a mapping file then only you can get list of your required object.

Join using Linq failing with Entity Framework 4.0

I'm having trouble running a join linq query against EF 4.0. Below is the code, stripped of all unnecessary statements, still reproducing the error)
using (var threadRepo = new Repo<Thread>())
using (var postRepo = new Repo<Post>())
{
var query = threadRepo
.Join(postRepo, t => t.PostId, s => s.Id, (t, s) => 1);
var array = query.ToArray();
}
Repo is my implementation of the repository pattern, and the join method looks like this:
public IEnumerable<TResult> Join<TInner, TKey, TResult>(
IEnumerable<TInner> inner,
Expression<Func<TEntity, TKey>> outerSelector,
Expression<Func<TInner, TKey>> innerSelector,
Expression<Func<TEntity, TInner, TResult>> result)
{
return _objectSet.Join(inner, outerSelector, innerSelector, result);
}
The error I get is
Unable to create a constant value of type 'Post'.
Only primitive types ('such as Int32, String, and Guid')
are supported in this context.
The same query works in LinqPad against the same database (though offcourse, there is not EF 4.0 there)
from t in Thread
join p in Post on t.PostId equals p.Id
select 1
Any clues on why Linq is giving me this exception?
Update
Based on a suggestion below, I tried using a common datacontext for both the repositories using a unit of work. However that doesn't seem to fix the issue. Below is the code I used
using (var uow = new UnitOfWork<CommunicationEntities>())
{
using (var threadRepo = new Repo<Thread>(uow))
using (var postRepo = new Repo<Post>(uow))
{
var query = threadRepo
.Join(postRepo, t => t.PostId, s => s.Id, (t, s) => 1);
var array = query.ToArray();
}
}
This gives me the same error as before.
Thanks
Jaspreet
A common mistake I have seen is that the data context is on the repository level and each repository uses a different data context - in this case that would explain the error. Instead your repositories all should share the same data context using the Unit of Work pattern.

NHibernate Search N+1 Issue

I'm using NHibernate Search for NHibernate 3.0 GA.
I have this code in my product repository:
public IList<Product> Find(string term)
{
var productFields = new[] { "Name", "Description" };
var importance = new Dictionary<String, float>(2) { { "Name", 4 }, { "Description", 1 } };
var analyzer = new StandardAnalyzer();
var parser = new MultiFieldQueryParser(
productFields,
analyzer,
importance);
var query = parser.Parse(term);
var session = Search.CreateFullTextSession(NHibernateSession.Current);
var tx = session.BeginTransaction();
var fullTextQuery = session.CreateFullTextQuery(query);
fullTextQuery.SetFirstResult(0).SetMaxResults(20);
var results = fullTextQuery.List<Product>();
tx.Commit();
return results;
}
In NH Profiler, I can see that a select statement is issued for every product found. What am I missing?
I found this thread from 2009 but presumably this bug has been fixed.
EDIT [06/06/2011]:
My property mappings as far as associations go are as follows:
mapping.HasManyToMany(c => c.Categories)
.Table("CatalogHierarchy")
.ParentKeyColumn("child_oid")
.ChildKeyColumn("oid")
.Cascade.None()
.Inverse()
.LazyLoad()
.AsSet();
mapping.HasMany(c => c.Variants)
.Table("CatalogProducts")
.Where("i_ClassType=2")
.KeyColumn("ParentOID")
.Cascade.SaveUpdate()
.AsSet();
I don't really want to eager fetch all categories.
As NHibernate.Search is unstable, I would use (and I did) Lucene.NET directly from my application - just to ask Lucene for objects' Ids and then load it using Session.Load().
Also you could change LazyLoad settings at class mapping level, not at relationship level.
Hope it helps.
EDIT: you could specify batch-size for relationships, so they wouldn't cause select N+1 problem
Are you referencing any lazy loaded properties in the product list that is returned by this method? If so, you can change the property mapping to "eager fetch".
I solved this in the end. I realised I had not wrapped the whole thing into a transaction. Once I did, the N+1 issue was gone.
Schoolboy error, but hey, you learn by your mistakes.