I have Users and Videos and I want to see users videos under user class, and videos user in video class; I don't know how to fill videos of user to that users class and videos user under video class.
Mappings >
public UserMap()
{
Id(x => x.UserId);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.Email);
Map(x => x.Password);
Map(x => x.Type);
HasMany(x => x.Videos);
}
public VideoMap()
{
Id(x => x.VideoId);
Map(x => x.UserId);
Map(x => x.VideoTypeId);
Map(x => x.Status);
Map(x => x.Image);
HasOne(x => x.User)
}
Classes >
public class User
{
public virtual int UserId { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string Email { get; set; }
public virtual string Password { get; set; }
public virtual int Type { get; set; }
public virtual List<Video> Videos { get; set; }
}
public class Video
{
public virtual int VideoId { get; set; }
public virtual int UserId { get; set; }
public virtual int VideoTypeId { get; set; }
public virtual string Status { get; set; }
public virtual string Image { get; set; }
public virtual User User { get; set; }
}
Method >
public static IList<Entities.Video.Video> All()
{
using (var session = NHibernateHelper.OpenSession())
{
IList<Entities.Video.Video> videos = session.Query<Entities.Video.Video>(
.Where(C => C.User.UserId == C.UserId).ToList();
return videos;
}
}
First, in your model class you should use IList rather than List.
and try with mappings
public UserMap()
{
Id(x => x.UserId);
Map(x => x.FirstName);
Map(x => x.LastName);
Map(x => x.Email);
Map(x => x.Password);
Map(x => x.Type);
HasMany(x => x.Videos).KeyColumn("keyColumn");
}
public VideoMap()
{
Id(x => x.VideoId);
Map(x => x.UserId);
Map(x => x.VideoTypeId);
Map(x => x.Status);
Map(x => x.Image);
References(x => x.User).Column("keyColumn");
}
where keyColumn is primary key of your table that contains videos.
and to get videos of user something like this
IList<Video> videos = session.CreateCriteria(typeof(Video)).CreateAlias("User", "user").Add(Restrictions.Eq("user.UserId", id)).List<Video>().ToList();
Related
I'm new in NHibernate I write code which is simple should insert into database information about users that's it
the code is below
UserClassModel
class Users
{
public virtual int id { get; set; }
public virtual string username { get; set; }
public virtual string password { get; set; }
public virtual string role { get; set; }
public virtual bool deleted { get; set; }
public virtual DateTime create_date { get; set; }
}
UserMapClass
class UserMap : ClassMap<Users>
{
public UserMap()
{
Id(x => x.id);
Map(x => x.username);
Map(x => x.password);
Map(x => x.deleted);
Map(x => x.role);
Map(x => x.create_date);
}
}
Connection where I try to insert data into database using NHibernate
class Connection
{
public Connection()
{
var sefact = createFactory();
using (var session = sefact.OpenSession())
{
using (var txt = session.BeginTransaction())
{
var users = new Users
{
username = "jakhongir",
password = "2356+"
};
session.Save(users);
}
}
}
private static ISessionFactory createFactory()
{
string connectionString = "Server=127.0.0.1; Port=5433; User Id=smartwarehouse; Password=$smart#2018;Database=warehouse;";
IPersistenceConfigurer config = PostgreSQLConfiguration.PostgreSQL82.ConnectionString(connectionString);
FluentConfiguration configuration = Fluently.Configure().Database(config).Mappings(m => m.FluentMappings.Add(typeof(UserMap)));
return configuration.BuildSessionFactory();
}
here is code I can't insert it into database it gives following errors
here is database part of
Rename your Model class to 'User' from 'Users' (Generally it's a good practice to use singular names for the model, as it represents a single entity)
class User
{
public virtual int id { get; set; }
public virtual string username { get; set; }
public virtual string password { get; set; }
public virtual string role { get; set; }
public virtual bool deleted { get; set; }
public virtual DateTime create_date { get; set; }
}
The mapping class must derive from ClassMap :
// Creating the map class
public UserMap:ClassMap<User>
{
// The constructor of Mapping class
public UserMap()
{
Id(x => x.id);
Map(x => x.username);
Map(x => x.password);
Map(x => x.deleted);
Map(x => x.role);
Map(x => x.create_date);
}
}
How can I create relation like this?
public class UserMap : ClassMap<User>
{
public UserMap()
{
Id(x => x.UserId);
Map(x => x.UserName);
Map(x => x.Password);
Map(x => x.FirstName);
Map(x => x.LastName);
HasManyToMany(x => x.FBFriends).Cascade.All().Table("UserFBFriend");
HasManyToMany(x => x.FBFriends).Cascade.All().Inverse().Table("UserFBFriend");
}
}
public class User : BaseClass<User>
{
public virtual int UserId { get; set; }
public virtual string UserName { get; set; }
public virtual string Password { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual IList<User> FBFriends { get; set; }
public User()
{
FBFriends = new List<User>();
}
public virtual void AddUserFBFriend(User user)
{
user.FBFriends.Add(this);
FBFriends.Add(user);
}
}
UPDATE
HasManyToMany(x => x.LeftFBFriends).Cascade.All().Table("UserFBFriend");
HasManyToMany(x => x.RightFBFriends).Cascade.All().Inverse().Table("UserFBFriend");
public virtual IList<User> LeftFBFriends { get; set; }
public virtual IList<User> RightFBFriends { get; set; }
public User()
{
LeftFBFriends = new List<User>();
RightFBFriends = new List<User>();
}
As discussed, we need two collections, representing both directions A-B, B-A
public virtual IList<User> LeftFBFriends { get; set; }
public virtual IList<User> RightFBFriends { get; set; }
And we'd need explicit column mapping:
HasManyToMany(x => x.LeftFBFriends)
.Table("UserFBFriend")
.ParentKeyColumn("LeftColumn")
.ChildKeyColumn("RightColumn")
.Cascade.All().Table("UserFBFriend");
HasManyToMany(x => x.RightFBFriends)
.Table("UserFBFriend")
.ParentKeyColumn("RightColumn")
.ChildKeyColumn("LeftColumn")
.Cascade.All()
.Inverse()
So, this way we do correctly instruct NHibernate, which column will play parent (this ID) and which will be the child (collection ID). We have to do that for both collections
Here there are my domain entities:
public class Province
{
private ICollection<City> _cities;
public virtual ICollection<City> Cities
{
get { return _cities ?? (_cities = new HashSet<City>()); }
set { _cities = value; }
}
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual double Latitude { get; set; }
public virtual double Longitude { get; set; }
}
public class City
{
private Province _province;
public virtual Province Province
{
get { return _province ?? (_province = new Province()); }
set { _province = value; }
}
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Latitude { get; set; }
public virtual string Longitude { get; set; }
}
Mappings:
public class ProvinceMap : EntityTypeConfiguration<Province>
{
public ProvinceMap()
{
this.ToTable("Province");
this.HasKey(p => p.Id);
this.Property(x => x.Id).HasColumnName("Id");
this.Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(x => x.Name).HasMaxLength(50).IsRequired();
this.Property(x => x.Latitude).IsRequired();
this.Property(x => x.Longitude).IsRequired();
//this.HasMany(x => x.Cities)
// .WithRequired(x => x.Province)
// .HasForeignKey(x => x.Id);
}
}
public class CityMap : EntityTypeConfiguration<City>
{
public CityMap()
{
this.ToTable("City");
this.HasKey(x => x.Id);
this.Property(x => x.Id).HasColumnName("Id");
this.Property(x => x.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(x => x.Name).HasMaxLength(50).IsRequired();
this.Property(x => x.Latitude).IsRequired();
this.Property(x => x.Longitude).IsRequired();
this.HasRequired(x => x.Province)
.WithMany(x => x.Cities)
.HasForeignKey(x => x.Id);
}
}
Context:
public class DataContext : DbContext
{
public DataContext(): base("DataContext")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<DataContext, Configuration>("DataContext"));
}
public DbSet<Province> Provinces { get; set; }
public DbSet<City> Cities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ProvinceMap());
modelBuilder.Configurations.Add(new CityMap());
//base.OnModelCreating(modelBuilder);
}
}
When I run the 'update-database' command at the Nuget Package Console, I have an error:
Invalid multiplicity in the element Role "City_Province_Source" in connection "City_Province". Because the Dependent Role refers to the key properties, the upper bound of the multiplicity properties Dependent Role must be equal to "1".
Logically, you are trying to define a 1-to-many relationship. Because City cannot be in many Provinces, and one Province can have many Cities.
In this case, you don't necessarily need to specify HasRequired and WithMany in your mapping.
Remove the following code from CityMap
this.HasRequired(x => x.Province)
.WithMany(x => x.Cities)
.HasForeignKey(x => x.Id);
Having ICollection<City> in Province table, and a property type of Province in City table is enough to establish the relationship.
The output will be like this.
I have a one to many relationship between my product and image entities. What I'm trying to achieve is to map a main image in the product entity, using Fluent mapping or LinqToNHibernate.
My classes:
public class Product {
public virtual int Id { get; set; }
public virtual IList<Image> images { get; set; }
}
public class Image {
public virtual int Id { get; set; }
public virtual Product Product { get; set; }
public virtual bool IsMain { get; set; }
}
My mappings:
public class ProductMap : ClassMap<Product> {
public ProductMap() {
Id(x => x.Id);
HasMany(x => x.images).KeyColumn("id_product");
}
}
public class ImageClassMap : ClassMap<Image> {
public ImageClassMap() {
Table("product_image");
Id(x => x.Id);
References(x => x.Product, "id_product");
Map(x => x.IsMain).Column("is_main");
}
}
I was able to achieve this with QueryOver as follows:
Image imageAlias = null;
var product = session.QueryOver<Product>()
.Where(x => x.Id == 2)
.Left.JoinQueryOver(x => x.images, () => imageAlias, x => x.IsMain)
.SingleOrDefault();
Is it possible to have a MainImage property in the Product class, where IsMain property is true, using Fluent mapping or LinqToNHibernate?
Yes, you can try,
public class Product {
...
public Image MainImage { get; set; }
}
and then the mapping,
public ProductMap() {
...
HasOne(product => product.MainImage).KeyColumn("main_image_id");
}
I am getting duplicates of child when updating entity.
Submission Code:
Report report = _ReportService.GetReport(id);
report.AddDocument(
new Document
{
Extension = qqfile.Substring(qqfile.Length - 3),
Path = g.ToString(),
Type = TypeHelper.GetDocumentType(report.Status),
User = MemberFactory.MemberInfo
}
);
report.Status = (ReportStatus)((int)report.Status + 1);
_reportRepository.SaveOrUpdate(report);
public class Document : BaseModel
{
public virtual string Path { get; set; }
public virtual string Extension { get; set; }
public virtual DocumentType Type { get; set; }
public virtual User User { get; set; }
public virtual Report Report { get; set; }
}
public class DocumentMap : ClassMap<Document>
{
public DocumentMap()
{
Id(x=> x.Id);
Map(x=> x.Extension);
Map(x => x.Path);
Map(x => x.CreateDate);
Map(x => x.LastModified);
Map(x => x.Type).CustomType<int>();
References<User>(x => x.User);
References<Report>(x => x.Report);
}
}
public class Report : BaseModel
{
public virtual Patient Patient { get; set; }
public virtual ReportStatus Status { get; set; }
public virtual DateTime AppointmentStart { get; set; }
public virtual DateTime AppointmentEnd { get; set; }
public virtual ReportType Type { get; set; }
public virtual IList<Document> Documents { get; set; }
public virtual long Kareo_Id { get; set; }
public Report()
{
this.Status = ReportStatus.New;
this.Documents = new List<Document>();
}
public virtual void AddDocument(Document document)
{
document.Report = this;
this.Documents.Add(document);
}
}
public class ReportMap : ClassMap<Report>
{
public ReportMap()
{
Id(x => x.Id);
Map(x => x.CreateDate);
Map(x => x.LastModified);
Map(x => x.AppointmentStart);
Map(x => x.AppointmentEnd);
Map(x => x.Type).CustomType<int>();
Map(x => x.Status).CustomType<int>();
Map(x => x.Kareo_Id);
References<Patient>(x => x.Patient);
HasMany<Document>(x => x.Documents)
.Inverse()
.Cascade.All();
}
}
Try adding AsSet to the mapping
HasMany<Document>(x => x.Documents)
.AsSet()
.Inverse()
.Cascade.All();
You would need to change IList to ICollection and initialize it with System.Collections.Generic.HashSet.
The cause of the problem is that you are probably adding the same document to the list twice and since it is not saved it gets inserted twice to the db.
Mapping of an entity i take it as document map:
you should add
References<User>(x => x.User).Cascade.None();
Cascade.None() will stop cascading any changes.
Also you can use intellisense to give you options you can use when you write .Cascade.
Rev 2
this should be for both mappings
References(x => x.User).Cascade.None(); References(x =>
x.Report).Cascade.None();