Searching through child objects nhibernate search? - nhibernate

I have this kind of relationship
Supplier -> has many Products
Both Supplier is indexed and products are indexed. I need (boss wants to) search through both the Supplier and all of the suppliers' products and list the resulting suppliers.
Is this possible in nhibernate.search/Lucene.NET??

Yes it is possible : http://ayende.com/blog/3992/nhibernate-search
See the given example, IndexEmbedded attribute means the "child" object or collection will be indexed too :
[Indexed]
public class Post
{
[DocumentId]
public virtual int Id { get; set; }
[IndexedEmbedded]
public virtual Blog Blog { get; set; }
[IndexedEmbedded]
public virtual User User { get; set; }
[Field(Index.Tokenized, Store = Store.Yes)]
public virtual string Title { get; set; }
[Field(Index.Tokenized)]
public virtual string Text { get; set; }
public virtual DateTime PostedAt { get; set; }
public virtual ISet<Comment> Comments { get; set; }
[IndexedEmbedded]
public virtual ISet<Category> Categories { get; set; }
[IndexedEmbedded]
public virtual ISet<Tag> Tags { get; set; }
}

Related

Can I reference single foreign key on multiple columns in a table? If yes, how to configure it in Entity Framework core

How can I generate above table like structure using Entity Framework core?
I am using code first approach to generate my tables from domain models which are as follows
public class Contact
{
public int ContactId { get; set; }
public string Email { get; set; }
public string Name { get; set; }
}
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
[ForeignKey("Contact")]
public int FirstContact { get; set; }
[ForeignKey("Contact")]
public int SecondContact { get; set; }
[ForeignKey("Contact")]
public int ThirdContact { get; set; }
public virtual Contact Contact { get; set; }
}
In the company table, I want foreign key on columns 'FirstContact', 'SecondContact', 'ThirdContact' which can refer to Contacts table.
I have also tried Fluent API but no success in same also.
Whenever I am running the add-migration command, I am getting this error:
There are multiple properties with the [ForeignKey] attribute pointing to navigation 'Company.Contact'. To define a composite foreign key using data annotations, use the [ForeignKey] attribute on the navigation.
I would appreciate any help regarding the same.
Thanks.
For multiple Navigation Properties, you need multiple Foreign Keys. EG
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public virtual Contact FirstContact { get; set; }
public virtual Contact SecondContact { get; set; }
public virtual Contact ThirdContact { get; set; }
}
And let EF Core create shadow properties for your FKs or with Foreign Key properties:
public class Company
{
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public int FirstCotactId {get; set;}
public virtual Contact FirstContact { get; set; }
public int SecondCotactId {get; set;}
public virtual Contact SecondContact { get; set; }
public int SecondCotactId {get; set;}
public virtual Contact ThirdContact { get; set; }
}

EF Code First not setting foreign key in one to one relationship

So I'm trying to create a simple Product-Preview 1 to 1 relationship as follows:
public class Product : BaseEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
public string name { get; set; }
public virtual EPS eps { get; set; }
public virtual Preview preview { get; set; }
[ForeignKey("userId")]
public virtual User user { get; set; }
public Guid userId { get; set; }
}
and
public class Preview : BaseEntity
{
[Key,ForeignKey("Product")]
public Guid Id { get; set; }
public string imagePath { get; set; }
public double width { get; set; }
public double height { get; set; }
public virtual List<TextPreview> Texts { get; set; }
public virtual List<ImagePlaceHolder> ImagePlaceHolders { get; set; }
[ForeignKey("ProductId")]
public virtual Product Product { get; set; }
public virtual Guid ProductId { get; set; }
}
I was expecting to have a foreign key in the Previews table that would point to a Product
but after running the migration I just get it as regular field
What I'm I doing wrong?
You almost have it you just missed one piece of the puzzle ...
[ForeignKey("ProductId")]
public virtual Product Product { get; set; }
You also need to add ...
public Guid ProductId { get; set; }
to the preview object.
It's also worth noting that the ForeignKey attrib can be put on either property, and the string must refer to the other one of the pair.
As it's currently written you are trying to make the Id property specify the value for both the primary key and the foreign key on the tables in question.
So your final code might look something like ...
public class Product : BaseEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid Id { get; set; }
[ForeignKey("User")]
public Guid UserId { get; set; }
public string name { get; set; }
public virtual EPS eps { get; set; }
public virtual Preview preview { get; set; }
public virtual User user { get; set; }
}
and
public class Preview : BaseEntity
{
[Key]
public Guid Id { get; set; }
[ForeignKey("Product")]
public Guid ProductId { get; set; }
public string imagePath { get; set; }
public double width { get; set; }
public double height { get; set; }
public virtual List<TextPreview> Texts { get; set; }
public virtual List<ImagePlaceHolder> ImagePlaceHolders { get; set; }
public virtual Product Product { get; set; }
}
As a side note I would also recommend against using concrete collection types like List<T> instead use something like IList<T> or ICollection<T> it promotes better code reuse and extensibility.

how to query navigation properties code-first MVC4

What is wrong here? I have a many to many between products and transactions. Trying to build the view but I can't get any intellisense for the query to load the ProductTransaction table.
entity 1
[Table("Transactions")]
public class Transaction
{
[Key]
public virtual int TID { get; set; }
public virtual int FromUserID { get; set; }
public virtual int ToUserId { get; set; }
public virtual int itemForId { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
entity 2
[Table("Products")]
public class Product
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual int ProductId { get; set; }
[Required]
[StringLength(50, ErrorMessage="Name can't be longer than 50 characters bitch")]
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual DateTime? UploadDate { get; set; }
public virtual byte[] ProductImage { get; set; }
[StringLength(25)]
public virtual string MimeType { get; set; }
public virtual int Views { get; set; }
public virtual int Qty { get; set; }
// Relations
public virtual UserProfile User { get; set; }
public virtual int UserId { get; set; }
public virtual int CategoryId { get; set; }
public virtual ICollection<Bag> Bags { get; set; }
public virtual ICollection<Transaction> Transactions{ get; set; }
}
controller method to see all transactions and trades: query has no intellisense for Products
public ViewResult GetTrades()
{
//Include is not recognizing any nav properties
var friend = db.Transactions.Include(a => a.Products);
}
many to many relationship
modelBuilder.Entity<Transaction>()
.HasMany(p => p.Products)
.WithMany(t => t.Transactions)
.Map(m =>
{
m.ToTable("ProductTransactions");
m.MapLeftKey("ProductId");
m.MapRightKey("TID");
});
DbExtensions.Include(this IQueryable, Expression<Func<T, TProp>>) is an extension method.
You need to include the namespace to access it as an extension method.
using System.Data.Entity;

Fluent nHIbernate - Map a referenced / embedded class to same table as parent

I have a flat view that consists of columns such as:
ResultID
ResultName
ResultTime
DisciplineCode
DisciplineName
DateModified
etc...
I have a Result class that currently matches the above schema (flat)
public class Result
{
public virtual string ResultID { get; set; }
public virtual string ResultName { get; set; }
public virtual decimal ResultTime { get; set; }
public virtual string DisciplineCode { get; set; }
public virtual string DisciplineName { get; set; }
public virtual DateTime DateModified { get; set; }
}
What I'd like, is to separate my Discipline properties into their own class like this:
public class Discipline
{
public virtual string DisciplineCode { get; set; }
public virtual string DisciplineName { get; set; }
}
And then change my Result class to:
public class Result
{
public virtual string ResultID { get; set; }
public virtual string ResultName { get; set; }
public virtual decimal ResultTime { get; set; }
public virtual Discipline Discipline { get; set; }
public virtual DateTime DateModified { get; set; }
}
So that the Discipline is embedded as a class.
The details come from the same table (or in my case, normalized view)
How can I map this with fluent nHibernate
I've looked at References, but not sure if that's right?
Component sorted this.
Didn't realize I'd actually asked this question already a few days ago (in a different form)
See my answer here - https://stackoverflow.com/a/11397884/131809

NHibernate Left Outer Join SubClass

I have 2 entities products and images. Not all images are product images, and images are a sub class of a file below are my entities. I need to find all of the images that are not associated to a product. I'm new to retrieval of entities and have tried numerous approaches. Any ideas or links would be greatly appreciated.
public class File
{
#region Feilds
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual Enumerations.File.FileType Type { get; set; }
public virtual string Extension { get; set; }
public virtual string Path { get; set; }
public virtual DateTime DateCreated { get; set; }
public virtual DateTime DateModified { get; set; }
#endregion
}
public class Image : File
{
#region Fields
public virtual string ImageName { get; set; }
public virtual string Description { get; set; }
public virtual bool Active { get; set; }
public virtual DateTime DateTaken { get; set; }
#endregion
}
public class Product
{
#region Properties
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual decimal Price { get; set; }
public virtual decimal Weight { get; set; }
public virtual bool IsDigital { get; set; }
public virtual DateTime DateCreated { get; set; }
public virtual IList<Category> ProductCategories { get; set; }
public virtual IList<ProductAttribute> ProductAttributes { get; set; }
public virtual IList<Image> ProductImages { get; set; }
#endregion
}
You can use a Critiria not exists subquery...
IList<Image> images = session.CreateCriteria<Image>("img")
.Add(Expression.Not(Subqueries.Exists(DetachedCriteria.For<ProductImageLink>("pil")
.SetProjection(Projections.Constant(1))
.Add(Expression.EqProperty("img.image_id", "pil.image_id")))))
.List<Image>();
Where ProductImageLink is the association table.
Should result in a query like...
select ... from image img where not exists(select 1 from productimagelink pil where img.image_id = pil.image_id);