I have a problem using QBE with NHibernate. I have a one-to-one relationship between a Person class and an Employee.
public class Person
{
public virtual Employee Employee { get; set; }
public virtual int Age { get; set; }
public virtual string Forename { get; set; }
public virtual string Surname { get; set; }
public virtual int PersonID { get; set; }
}
public class Employee
{
public virtual int PersonID { get; set; }
public virtual string PayRollNo { get; set; }
public virtual int Holidays { get; set; }
public virtual Person Person { get; set; }
}
As an example, I want to get all Employees where Employee.Forename="John" and Employee.Person.PayRollNo = "231A". I was wondering if I could use Query By Example to do this?
I have not been able to find a definitive "no" but I haven't been able to get this work. I've found that QBE is promising but unfortunately not very useful due to the following limitations:
Cannot query related objects.
Requires public parameterless constructor.
Initialized properties are included in query unless specifically excluded using ExcludeProeprty. For example, bool properties are restricted to false in the where clause, DateTime as DateTime.MinValue. This makes the query very brittle because class modifications may have bad side effects.
Related
I am working on Entity Framework Core Code First approach and ASP.Net Core 2.1 making 3 tables:
Person class
public class Person
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public PeopleProfessions PeopleProfessions { get; set; }
}
Professions' class
public class Profession
{
public string Id { get; set; }
public string Name{ get; set; }
public PeopleProfessions PeopleProfessions { get; set; }
}
peopleprofessions' class
public class peopleprofessions
{
[ForeignKey("PersonId ")]
public string PersonId { get; set; }
public ICollection<Person> People { get; set; }
[ForeignKey("ProfessionId")]
public string ProfessionId{ get; set; }
public ICollection<Profession> Professions { get; set; }
}
On my Context:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<peopleprofessions>().HasKey(up => new { up.PersonId, up.ProfessionId });
}
Bearing this in mind:
People can have multiple professions.
The professions table is only for reading stored data like "Accountant".
I have doubts about how I can make table 3 only contain the foreigners and that it can meet the needs that I just mentioned.
I have tried to make the relationship appropriately but I also noticed that in tables 1 and 2 it requests both Id of the table people's professions.
I don't know if I am lost or if I am looking wrong or if there is an alternative to that situation. Thanks for any help you can give me.
You have the use of Collections on the navigation items a bit backwards. For your primary entities (Person and Profession), they should have collections, since it's one-to-many. But for the PeopleProfessions, each record is a single link to a specific entity, so no collection there just a direct object reference.
public class Person
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<PeopleProfessions> PeopleProfessions { get; set; }
}
public class Profession
{
public string Id { get; set; }
public string Name{ get; set; }
public ICollection<PeopleProfessions> PeopleProfessions { get; set; }
}
public class PeopleProfessions
{
public string PersonId { get; set; }
public Person Person { get; set; }
public string ProfessionId { get; set; }
public Profession Profession { get; set; }
}
You can, but don't need to specify a ForeignKey attribute because you are following EFs naming conventions(it will figure it out for you). Your OnModelCreating looks correct for the composite key.
You may want to consider removing the plural from PeopleProfessions (just call the class PeopleProfession) since one instance represents a single People-Profession relationship. I typically do this and but the navigation name in the entities remains plural, since it can represent more than one, i.e.
public ICollection<PeopleProfession> PeopleProfessions { get; set; }
With ASP.NET MVC Core and Entity Framework Core I'm trying to create a simple website.
I've defined my Model:
public class Club
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Team> Teams { get; set; }
}
public class Team
{
[Key]
public int Id { get; set; }
public int ClubId { get; set; }
[MaxLength(32)]
public string Name { get; set; }
public virtual Club Club { get; set; }
}
As well as the corresponding View Models:
public class ClubViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<TeamViewModel> Teams { get; set; }
}
public class TeamViewModel
{
public int Id { get; set; }
public int ClubId { get; set; }
public string Name { get; set; }
public virtual ClubViewModel Club { get; set; }
}
I've defined an Automapper Profile with the corresponding mappers:
CreateMap<Club, ClubViewModel>();
CreateMap<ClubViewModel, Club>();
CreateMap<Team, TeamViewModel>();
CreateMap<TeamViewModel, Team>();
I try to load a Club entity, with the navigation property Teams included (_context.Club.Include(c => c.Teams).ToList()). This works as expected, it returns a Club with a list of Teams. But when I try to map this instance to a ClubViewModel, I get an 502.3 error and my debug session is ended immediately.
It seems like I am missing something trivial, but I simply do not see it. There's no information in the Windows Event Log and I can't find any usefull information in the IIS Express logging (%userprofile%\documents\IISExpress)
What is causing the crash?
You can't perform this mapping because it is circular. You'll have to remove this line
public virtual ClubViewModel Club { get; set; }
from your TeamViewModel and the mapping should work as expected.
I an fairly new to MVC, and have created an MVC4 application using EF-database-first. The database does not contain foreign key definitions and I can't add them (I don't own the database). Here are two example classes from the database:
public partial class Allocation
{
public int AllocID { get; set; }
public int DeptID { get; set; }
public decimal AllocationPercent { get; set; }
}
public partial class Department
{
public int DeptID { get; set; }
public string DeptName { get; set; }
public string Account { get; set; }
}
The default Allocation Index page shows the department ID. I want to show the department name instead. How can I do this without navigation properties?
I tried
public class AllocationController : Controller
{
private Entities db = new Entities();
//
// GET: /Allocation/
public ActionResult Index()
{
return View(db.Allocation.Include(d => d.DeptID).ToList());
}
...
but this gives an error ("A specified Include path is not valid. The EntityType 'TESTModel.Allocation' does not declare a navigation property with the name 'DeptID'.")...
I'm not sure how to code eager-loading or explicit-loading without navigation properties either, which prompted this question. Efficiency-wise, I don't believe it matters which way I load the related information, so any help in any direction would be appreciated.
The database does not have to have definitions, as long as the fields are there and the entities have been placed in the database with referential integrity in mind. All you need to do is let entity framework know about the relationship. This is done with the virtual keyword to create "Navigational Properties".
public partial class Allocation
{
public int AllocID { get; set; }
public int DeptID { get; set; }
public decimal AllocationPercent { get; set; }
public virtual Department Department { get; set; } /* this is your nav property */
}
public partial class Department
{
public int DeptID { get; set; }
public string DeptName { get; set; }
public string Account { get; set; }
}
Now you can do:
db.Allocation.Include(a => a.Department).ToList()
There may be an error which requires you to use a foreign key definition (although I do not think so). If this is the case, you will need to decorate your navigation property like this
[ForeignKey("DeptID")]
public virtual Department Department { get; set; }
You may also try it this way:
public int AllocID { get; set; }
[ForeignKey("Department")]
public int DeptID { get; set; }
public decimal AllocationPercent { get; set; }
public virtual Department Department { get; set; }
With navigation properties, Travis J's answer is what you need.
If you don't want to use navigation properties, assuming your DB context has a set called Departments, you could do smth like this:
var deptId = db.Allocation.DeptID;
var departments = db.Departments.Where(p => p.DeptID == deptId);
return View(departments.ToList());
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
When automapping a joined subclass in fluent nhibernate, I can't figure out how to give the joined subclass a primary key.
public class Address:Entity {
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
public virtual string State { get; set; }
public virtual string Zip { get; set; }
public virtual string Phone { get; set; }
public virtual string Fax { get; set; }
public virtual IList<Location> Locations { get; set; }
}
public class Location:Address {
public virtual Address BillingAddress { get; set; }
public virtual string OfficeHours { get; set; }
public virtual string PatientAgeRestrictions { get; set; }
public virtual bool WheelchairAccess { get; set; }
public virtual string ContactPerson { get; set; }
public virtual string ContactEmail { get; set; }
public virtual string ContactPhone { get; set; }
public virtual string ContactFax { get; set; }
public virtual string TaxId { get; set; }
}
I want Location to have it's own id "location_ id" with it's own sequence. Then I want that mapped to address through an address_id column.
Right now it's generating the location with "addressid" as the primary key, which isn't what I want. How do I change this with the automapping?
I'm not sure you have a joined-subclass relationship. That is, by definition a joined subclass has the same ID as its parent class. For example, you might have a Person entity stored in your database for generic "people" information like name/age/etc and then an Employee subclass entity which is stored in a different table and holds data like position, salary, and dates of employment. So an Employee is a subtype of Person and to get the full "Employee-Person" object, you must join the two tables on their primary keys (e.g. SELECT * FROM Employee INNER JOIN Person ON Employee.Employee_id = Person.Person_id).
Are you sure about your relational model here? Is Location truly a subtype of Address? Inferring a bit from your property names, it seems to me that this is not what you intend. It seems like you probably have a many-to-many between an Address and an Organization (that is, there may be many "organizations" at the same address and an "organization" may have many addresses), with a "contact person" for the organization at a specific address. In which case you should map "organization", "contact", and another entity that defines the relationship between Address and "organization".