How do you do joins in hibernate activerecord? - c#

How do I do a join that would return me results similar to-
SELECT * FROM Project LEFT JOIN ProjectRegion ON ProjectRegion.id = Project.projectRegion
I currently use the syntax-
Project[] projects = Project.FindAll();
My tables are setup with ActiveRecord/hibernate as follows -
[ActiveRecord]
public class ProjectRegion : ActiveRecordBase<ProjectRegion>
{
private int id;
private String title;
public ProjectRegion()
{
}
[PrimaryKey]
public int Id
{
get { return id; }
set { id = value; }
}
[Property]
public String Title
{
get { return title; }
set { title = value; }
}
}
[ActiveRecord]
public class Project : ActiveRecordBase<Project>
{
private int id;
private String projectNumber;
private String projectRegion;
public Project()
{
}
[PrimaryKey]
public int Id
{
get { return id; }
set { id = value; }
}
[Property]
public String ProjectInternalCode
{
get { return projectNumber; }
set { projectNumber = value; }
}
[Property]
public String ProjectRegion
{
get { return projectRegion; }
set { projectRegion = value; }
}
...

If you declare the ProjectRegion property in the Project class to be of type ProjectRegion instead of string, when NHibernate fetches a Project it will automatically join (according to a fetch policy) the ProjectRegion table.

Related

object data null after get request in Dotnet webapi project

I have created two model classes Organisation.cs and Employee.cs
public class Organisation
{
private static string organisationName="FALCON";
private int employeeCount=2;
private string ceoName;
private List<string> departmentNames;
[JsonIgnore]
private List<Employee> employees;
private List<Address> addesses;
private bool isCeoChangeAvailable= true;
public string OrganisationName
{
get {return organisationName;}
set {organisationName = value;}
}
public int EmployeeCount
{
get {return employeeCount;}
set { employeeCount = value; }
}
public string CeoName
{
get { return ceoName; }
set { ceoName = value; }
}
public List<string> Departments
{
get { return departmentNames; }
set { departmentNames = value; }
}
[IgnoreDataMember]
public List<Employee> Employees
{
get {return employees; }
set {employees=value; }
}
public List<Address> OfficeAdresses
{
get {return addesses; }
set { addesses = value; }
}
public bool IsCeoChange
{
get{ return isCeoChangeAvailable; }
set { isCeoChangeAvailable = value; }
}
public Organisation(string ceoName,List<string> departments,List<Address> addresses)
{
this.CeoName = ceoName;
this.Departments = departments;
this.OfficeAdresses = addresses;
}
public Organisation() { }
}
and an employee class
public class Employee
{
private Guid employeeId;
private string name;
private string departmentName;
private bool isManager;
private int salary;
public Guid Id
{
get
{ return employeeId;}
set
{ employeeId = value;}
}
public string Name
{
get
{ return name;}
set
{ name = value;}
}
public bool IsManager
{
get
{ return isManager;}
set
{ isManager = value;}
}
public string DepartmentName
{
get { return departmentName;}
set { departmentName = value;}
}
public int Salary
{
get { return salary; }
set { salary = value; } }
public Employee()
{
}
}
have a two controllers for Employee and Organisation, I am trying to post Organisation data and storing it in a variable.
In my organisaiton controller I have this method
public IActionResult PostOrganisationData(Organisation organisation)
{
_organisationData.PostOrganisationDetails(organisation);
return Created(HttpContext.Request.Scheme + "://" + HttpContext.Request.Host + HttpContext.Request.Path + "/" + organisation.OrganisationName, organisation);
}
In my datalayer have a class MockEmployeeData which implements IOrganisationData interface
here is the code where I am constructing the Organisation object and assigning it to an instance of Organisation object. During the request The organisation object holds the assigned data. Here is the code
private Organisation organisation = new Organisation();
public Organisation PostOrganisationDetails(Organisation organisation)
{
Organisation organisationObject = new Organisation(organisation.CeoName, organisation.Departments, organisation.OfficeAdresses);
organisation = organisationObject;
return organisation;
}
When I call the Get action method which gets the organisation details from the controller the previously assigned object has properties with null. Here is the get method
[HttpGet]
[Route("api/[controller]")]
public IActionResult GetOrganisationDetails()
{
var organisationData=_organisationData.GetOrganisationData();
return Ok(organisationData);
}
public Organisation GetOrganisationData()
{
Organisation organisationObject = new Organisation();
organisationObject = organisation;
return organisationObject;
}
Here in this method I,m assigning the variable which holds the previously assigned data from post request and getting back the object where all properties have gone null now.Please help me solve this
You need to make your properties in your Organisation model class to nullable. Now you can do this by either manually making each property nullable in your class:
public class Organisation
{
public string? OrganisationName
{
get {return organisationName;}
set {organisationName = value;}
}
public int? EmployeeCount
{
get {return employeeCount;}
set { employeeCount = value; }
}
public string? CeoName
{
get { return ceoName; }
set { ceoName = value; }
}
public List<string?> Departments
{
get { return departmentNames; }
set { departmentNames = value; }
}
....so on
Or you can globally enable this property by editing your csproj file which contains your project properties:
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

I dont understand the error.. I think as far as I know there is a dataType, but I dont see how?

In the code below I hope that I specify correctly whats wrong. I need to be able to call item.departments.dept_Type and that should be possible because of the association that I have made. I don't need to create inner joins on a query to get the data if I understand correctly.
This is my PersonClass
namespace DATALAYER.DataHandler
{
[Table(Name = "People")]
public class Person
{
private int _DepartmentID;
public EntityRef<Department> _Department;
public Person() { this._Department = new EntityRef<Department>(); }
private int _ID;
[Column(IsPrimaryKey =true, Storage ="_ID")]
public int ID
{
get { return this._ID; }
set { this._ID = value; }
}
private string _p_FirstName;
[Column(Storage = "_p_FirstName")]
public string p_FirstName
{
get { return this._p_FirstName; }
set { this._p_FirstName = value; }
}
private string _LastName;
[Column(Storage = "_LastName")]
public string p_LastName
{
get { return this._LastName; }
set { this._LastName = value; }
}
private string _EmailAddress;
[Column(Storage = "_EmailAddress")]
public string p_EmailAddress
{
get { return this._EmailAddress; }
set { this._EmailAddress = value; }
}
private string _Password;
[Column(Storage = "_Password")]
public string p_Password
{
get { return this._Password; }
set { this._Password = value; }
}
private string _SSID;
[Column(Storage = "_SSID")]
public string p_SSID
{
get { return this._SSID; }
set { this._SSID = value; }
}
private string _DOB;
[Column(Storage = "_DOB")]
public string p_DOB
{
get { return this._DOB; }
set { this._DOB = value; }
}
private string _CellNumber;
[Column(Storage = "_CellNumber")]
public string p_CellNumber
{
get { return this._CellNumber; }
set { this._CellNumber = value; }
}
[Column(Storage = "_DepartmentID", DbType = "Int")]
public int p_Department_dept_ID
{
get { return this._DepartmentID; }
set { this._DepartmentID = value; }
}
[Association(Storage = "_DepartmentID", ThisKey = "p_Department_dept_ID")]
public Department Department
{
get { return this._Department.Entity; }
set { this._Department.Entity = value; }
}
}
}
This is my Department code
namespace DATALAYER.DataHandler
{
[Table(Name = "Departments")]
public class Department
{
//private EntitySet<Person> _Person;
//public Department()
//{
// this._Person = new EntitySet<Person>();
//}
private int _DepartmentID;
[Column(IsPrimaryKey = true, Storage = "_DepartmentID")]
public int dept_ID
{
get { return this._DepartmentID; }
set { this._DepartmentID = value; }
}
private string _deptType;
[Column(Storage = "_deptType")]
public string dept_Type
{
get { return this._deptType; }
set { this._deptType = value; }
}
//[Association(Storage = "_Person", OtherKey = "ID")]
//public EntitySet<Person> Persons
//{
// get { return this._Person; }
// set { this._Person.Assign(value); }
//}
}
}
Now the problem I'm thinking is that there is a problem with datatypes between the primary key of the person and a foreign key the departments. But Since they are both int I don't see how that can be a problem.
If someone can just explain my problem to cleary if Im wrong or something or help me with a solution pls.
Added this class
namespace DATALAYER.DataHandler
{
public class SHSdb2 : DataContext
{
public Table<Person> People;
public Table<Department> Department;
//public Table<Address> Address;
public SHSdb2(string connection) : base(connection) { }
}
}
Person table
Department table
Without this code it works but then I can only call stuff inside the table
[Column(Storage = "_DepartmentID", DbType = "Int")]
public int p_Department_dept_ID
{
get { return this._DepartmentID; }
set { this._DepartmentID = value; }
}
[Association(Storage = "_DepartmentID", ThisKey = "p_Department_dept_ID")]
public Department Department
{
get { return this._Department.Entity; }
set { this._Department.Entity = value; }
}
Seems like I fixed it with this not sure if its a fix or I just lucky if someone can still maybe explain this to me it would be much appreciated.
var personQuery =
from per in db.People
where per.p_FirstName == "Christian"
select per.Department;
I'm thinking by specifying that it needs to get the data from department it would allow it in the foreach.

How to use the Same Class on Client as on the Service?

How can I pass an entire defined class through a WCF service? I have the class defined on both the service and client side. I keep getting an error:
Best overloaded method match has some invalid arguments.
The whole class was copied from the client-side to the service-side.
Client side calling:
TransferProxy.PutTransferOnService(Transfer);
Defined on service:
[OperationContract]
bool PutTransferOnService(TypeTransfer Transfer);
I don't want to access individual items on the class from the client, I just want to move the WHOLE populated object through and do processing on the server side.
[DataContract]
public class TypeTransfer
{
private string userID;
private string transferNum;
private DateTime effectiveDate;
private int unitCount;
private int skuCount;
private string reason;
private string localStatus;
private string destStatus;
private string carrier;
private string sourceStore;
private string destinationStore;
private string inSeal;
private string outSeal;
[DataMember]
private List<TypeSOQ> correspondingSOQ = new List<TypeSOQ>();
[DataMember]
private List<TypeProductList> ProductList = new List<TypeProductList>();
public TypeTransfer() { }
// Function adds single item to transfer object
public void AddItem(int ProductID, string SKU, string PrimarySKU, string SCC, string ProductDescription, int TransferQty)
{
ProductList.Add(new TypeProductList
{
productID = ProductID,
sku = SKU,
primaryUPC = PrimarySKU,
scc = SCC,
description = ProductDescription,
transferQty = TransferQty
});
}
// Add SOQ to transfer object (can support multiple SOQ's)
public void AddSOQ(TypeSOQ soq)
{
correspondingSOQ.Add(soq);
}
// Function returns number of skus in Product List
public int GetSKUTotal()
{
return ProductList.Count();
}
// Function returns total number of items in transfer
public int GetItemTotal()
{
int itemtotal = 0;
for (int i = 0; i < ProductList.Count(); i++)
{
itemtotal += ProductList[i].transferQty;
}
return itemtotal;
}
// Return entire SOQ list
public List<TypeSOQ> GetSOQs()
{
return correspondingSOQ;
}
// Returns full product list in transfer object
public List<TypeProductList> GetProductList()
{
return ProductList;
}
[DataMember]
public string UserID
{
get { return userID; }
set { userID = value; }
}
[DataMember]
public string TransferNum
{
get { return transferNum; }
set { transferNum = value; }
}
[DataMember]
public DateTime EffectiveDate
{
get { return effectiveDate; }
set { effectiveDate = value; }
}
[DataMember]
public int UnitCount
{
get { return unitCount; }
set { unitCount = value; }
}
[DataMember]
public string Reason
{
get { return reason; }
set { reason = value; }
}
[DataMember]
public string LocalStatus
{
get { return localStatus; }
set { localStatus = value; }
}
[DataMember]
public string DestStatus
{
get { return destStatus; }
set { destStatus = value; }
}
[DataMember]
public string Carrier
{
get { return carrier; }
set { carrier = value; }
}
[DataMember]
public string SourceStore
{
get { return sourceStore; }
set { sourceStore = value; }
}
[DataMember]
public string DestStore
{
get { return destinationStore; }
set { destinationStore = value; }
}
[DataMember]
public string InSeal
{
get { return inSeal; }
set { inSeal = value; }
}
[DataMember]
public string OutSeal
{
get { return outSeal; }
set { outSeal = value; }
}
[DataMember]
public int SKUCount
{
get { return skuCount; }
set { skuCount = value; }
}
}
You said - The whole class was copied from the client-side to the service-side.
You don't need to copy your class to server side. just define your class in a separate library and give reference of that same library to both client and server.

C# to Java Conversion

I'm having trouble converting especially the getter and setter.
public class CartItem : IEquatable<CartItem>
{
#region Attributes
public int Quantity { get; set; }
private int _productId;
public int ProductId
{
get { return _productId; }
set
{
_product = null;
_productId = value;
}
}
private Product _product = null;
public Product Prod
{
get
{
if (_product == null)
{
_product = new Product(ProductId);
}
return _product;
}
}
public string Name
{
get { return Prod.ProductName; }
}
public string Description
{
get { return Prod.Description; }
}
public float UnitPrice
{
get { return Prod.UnitPrice; }
}
public float TotalPrice
{
get { return UnitPrice * Quantity; }
}
#endregion
#region Methods
public CartItem(int productId)
{
this.ProductId = productId;
}
public bool Equals(CartItem item)
{
return item.ProductId == this.ProductId;
}
#endregion
}
sample of getters and setters in Java:
public class Employee {
private int empId;
private String name;
private int age;
public Employee(int empId, String name, int age) {
this.empId = empId;
this.name = name;
this.age = age;
}
// getters & setters
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
using your code:
public class Sample {
private int _productId;
public int get_productId() {
return _productId;
}
public void set_productId(int productId) {
_productId = productId;
}
private Product _product = null;
public Product get_product() {
if (_product == null) {
_product = new Product();
}
return _product;
}
public void set_product(Product product) {
_product = product;
}
}
and something more:
public class Product {
String desription;
public String getDesription() {
return desription;
}
public void setDesription(String desription) {
this.desription = desription;
}
}
//this is your hidding delegation getter only in main class (Sample in my samples)
public String getDescription(){
return _product.getDesription();
}
Java getters and setters aren't as easy to use as C#'s. In Java, every getter and setter has to be explicitly defined, rather than using the shorthand you have there.
For example, for your code "public int ProductId", you would need a line defining the variable, in addition two methods (a getter and setter) as follows:
private int _productId;
public void setProductId(int anId)
{
_productId = anId;
}
public int getProductId()
{
return _productId;
}
You'd need to define similar variable declarations and getter/setter methods for each variable you have.

Errors: How to save a many-to-many relationship in Castle Active Record?

I've been trying for hours to get many-to-many relationship to save with Castle ActiveRecord. What am I doing wrong? I can't find anything in the documentation or on google. There is data in the database.
Courses have a many to many relationship with Books.
Test code.
Database.Course c = new Database.Course();
c.Number = "CS 433";
c.Name = "Databases";
c.Size = 34;
c.Books = Database.Book.FindAll();
c.Save();
Also doesn't work
foreach(Database.Book b in Database.Book.FindAll()){
c.Books.Add(b);
}
Database Classes
[ActiveRecord]
public class Course : ActiveRecordValidationBase<Course>
{
private int? id;
private string number;
private string name;
private string description;
private int size; //number of students in class
//references
private IList books = new ArrayList();
public override string ToString()
{
return FormattedName;
}
public string FormattedName
{
get
{
return string.Format("{0} - {1}", Number, Name);
}
}
[PrimaryKey]
public int? Id
{
get { return id; }
set { id = value; }
}
[Property, ValidateNonEmpty]
public string Number
{
get { return number; }
set { number = value; }
}
[Property, ValidateNonEmpty]
public string Name
{
get { return name; }
set { name = value; }
}
[Property(ColumnType="StringClob")]
public string Description
{
get { return description; }
set { description = value; }
}
[Property]
public int Size
{
get { return size; }
set { size = value; }
}
[HasAndBelongsToMany(typeof(Book),
Table = "BookCourse", ColumnKey = "course_id", ColumnRef = "book_id", Inverse = true)]
public IList Books
{
get { return books; }
set { books = value; }
}
}
[ActiveRecord]
public class Book : ActiveRecordValidationBase<Book>
{
private int? id;
private string title;
private string edition;
private string isbn;
private bool is_available_for_order;
//relations
private IList authors = new ArrayList();
private IList bookordercount = new ArrayList();
private IList courses = new ArrayList();
private Inventory inventory;
public override string ToString()
{
return FormattedName;
}
public string FormattedName
{
//*
get {
string str;
if (Edition == null || Edition == "")
str = Title;
else
str = string.Format("{0} ({1})", Title, Edition);
if (Authors.Count != 0)
{
return string.Format("{0} by {1}", str, FormattedAuthors);
}
else
{
return str;
}
}
/*/
get
{
return Title;
}
//*/
}
public string FormattedAuthors
{
get
{
if (Authors.Count == 0) return "";
StringBuilder sb = new StringBuilder();
int i = 0, end = Authors.Count;
foreach (Author a in Authors)
{
i++;
sb.Append(a.FormattedName);
if (i != end) sb.Append("; ");
}
return sb.ToString();
}
}
[PrimaryKey]
public int? Id
{
get { return id; }
set { id = value; }
}
[Property, ValidateNonEmpty]
public string Title
{
get { return title; }
set { title = value; }
}
[Property]
public string Edition
{
get { return edition; }
set { edition = value; }
}
[Property, ValidateNonEmpty]
public string Isbn
{
get { return isbn; }
set { isbn = value; }
}
[Property]
public bool IsAvailableForOrder
{
get { return is_available_for_order; }
set { is_available_for_order = value; }
}
//relations
[HasAndBelongsToMany(typeof(Author),
Table = "BookAuthor", ColumnKey = "book_id", ColumnRef = "author_id")]
public IList Authors
{
get { return authors; }
set { authors = value; }
}
[HasMany(typeof(BookOrderCount), Table = "BookOrderCounts", ColumnKey = "BookId")]
public IList BookOrderCount
{
get { return bookordercount; }
set { bookordercount = value; }
}
[HasAndBelongsToMany(typeof(Course),
Table = "BookCourse", ColumnKey = "book_id", ColumnRef = "course_id")]
public IList Courses
{
get { return courses; }
set { courses = value; }
}
[OneToOne]
public Inventory Inventory
{
get { return inventory; }
set { inventory = value; }
}
}
Make sure you put the Inverse = true where you want it. From the Castle AR docs,
It is wise to choose one side of the
relation as the owner. The other side,
the non-writable, need to use
Inverse=true.
Put the Inverse = true on the other side of the relationship, like this:
[HasAndBelongsToMany(typeof(Book),
Table = "BookCourse", ColumnKey = "course_id", ColumnRef = "book_id")]
public IList<Book> Books
[HasAndBelongsToMany(typeof(Course),
Table = "BookCourse", ColumnKey = "book_id", ColumnRef = "course_id", Inverse = true)]
public IList<Course> Courses
You also have to add attributes to the top of both classes - at the moment they don't know what tables they're mapped to. Currently you have this:
public class Course : ActiveRecordBase<Course>
Add this (where "course" is the name of your Course table):
[ActiveRecord("course")]
public class Course : ActiveRecordBase<Course>

Categories