NHibernate Projection to DTO - web-services

I am unfamiliar with NHibernate projection. I am attempting to use it so I can return a List<> rather that an IList<>. I am not having much luck with projecting to the DTO as of yet. I have the following query and Domain objects. So to begin I am just trying to get a list of Orders given an EmployeeID. I am looping through the resulting list and adding it to a List because I wish to be able to serialize this list. Can anyone tell me how far off I am with the Projection? I have searched and found some examples that are not similar to my own. Basically.. I just want to create a List of of the DTOs.
Thanks!
public List<EmployeeOrder> GetEmployessOrdersDTO(int empid)
{
var emporders = new List<EmployeeOrder>();
ICriteria criteriaSelect = NHibernateSessionManager.Instance.GetSession().CreateCriteria(typeof (Orders))
.CreateCriteria("Employees")
.Add(Expression.Eq("EmployeeID", empid));
criteriaSelect.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("Products"), "OrderedProducts"));
criteriaSelect.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean(typeof(EmployeeOrder)));
criteriaSelect.List<EmployeeOrder>();
foreach (var order in emporders)
{
emporders.Add(order);
}
return emporders;
}
Orders:
public class Orders
{
public virtual int OrderID { get; private set;}
public virtual string CustomerID { get; set; }
public virtual DateTime OrderDate { get; set; }
public virtual DateTime RequiredDate { get; set; }
public virtual DateTime ShippedDate { get; set; }
public virtual Employees Employee { get; set; }
public virtual IList<Products> Products { get; private set; }
}
Employees:
public class Employees
{
public virtual int EmployeeID { get; private set;}
public virtual string LastName { get; set;}
public virtual string FirstName { get; set;}
public virtual string City { get; set; }
public virtual DateTime HireDate { get; set; }
public virtual string Title { get; set; }
public virtual IList<Orders> Orders { get; private set; }
}
EmployeeOrderDTO:
public class EmployeeOrder
{
public virtual string EmployeeName { get; set; }
public virtual string EmployeeTitle { get; set; }
public virtual DateTime RequiredDate { get; set; }
public virtual List<Products> OrderedProducts { get; set; }
}

In nHibernate 2.1, the .List() method actually already returns a List type, so you can just cast:
var list = (List<EmployeeOrder>)criteriaSelect.List<EmployeeOrder>();
However, if you want to be future safe and not depend on assumptions based on the implementation of the current nHibernate, I'd write an extension method accepting ICriteria:
public static List<T> ToList<T>(this ICriteria criteria)
{
return criteria.List<T>().ToList();
}

Change
criteriaSelect.List<EmployeeOrder>();
to
List<EmployeeOrder> employeeOrders = criteriaSelect.List<EmployeeOrder>() as List<EmployeeOrder>;

Related

Method does not exist or incorrect signature : void

I'm getting the below error while saving the test class. Can anyone help on this please?
Error :
Method does not exist or incorrect signature: void exceptionLogFromFlow(List<CS_ExceptionLoggerFlowTest.WrapperClass>) from the type CS_ExceptionLoggerFlow
Test Class:
#istest
Public class CS_ExceptionLoggerFlowTest {
#istest
static void SingleExceptionMethod() {
WrapperClass wlu=new wrapperClass();
wlu.apexClass ='CS_ExceptionLoggerFlow';
Wlu.methodName='createExceptionLog';
Wlu.exceptionMessage='message';
Wlu.exceptionDated=System.today();
Wlu.isAPIFailure = false;
Wlu.userName='userName';
list<WrapperClass> wpl= new list<WrapperClass>();
wpl.add(wlu);
Test.startTest();
CS_ExceptionLoggerFlow.exceptionLogFromFlow(wpl);
Test.stopTest();
}
public class WrapperClass {
public String apexClass;
public String methodName;
public String exceptionMessage;
public DateTime exceptionDated;
public Boolean isAPIFailure;
public String userName;
}
}
Main Class:
public class CS_ExceptionLoggerFlow {
#InvocableMethod(label='Exception Log From Flow')
public static void exceptionLogFromFlow(List<Params> inputVars) {
String serializedstring=JSON.serialize(inputVars);
String returnString = serializedstring.substring(1,serializedstring.length()-1);
createExceptionLog(returnString);
}
#future
public static void createExceptionLog(String futureParams){
List<ExceptionLogger__c> logList = new List<ExceptionLogger__c>();
WrapperClass value = (WrapperClass) JSON.deserialize(futureParams, WrapperClass.class);
List<WrapperClass> wpl= new List<WrapperClass>();
wpl.add(value);
for(WrapperClass vlu:wpl){
ExceptionLogger__c log = new ExceptionLogger__c();
log.Apex_Class__c = vlu.apexClass;
log.Method_Name__c = vlu.methodName;
log.Description__c = vlu.exceptionMessage;
log.Exception_Dated__c = vlu.exceptionDated;
log.API_Failure__c = vlu.isAPIFailure;
log.User_Name__c = vlu.userName;
logList.add(log);
}
insert logList;
}
public class Params {
#InvocableVariable public String apexClass;
#InvocableVariable public String methodName;
#InvocableVariable public String exceptionMessage;
#InvocableVariable public DateTime exceptionDated;
#InvocableVariable public Boolean isAPIFailure;
#InvocableVariable public String userName;
}
public class WrapperClass {
public String apexClass;
public String methodName;
public String exceptionMessage;
public DateTime exceptionDated;
public Boolean isAPIFailure;
public String userName;
}
}

Spring-batch ItemProcessor data in the form of a list to model

I'm using a custom itemReader to read data from an external rest API, and it's working great. However, the problem arises when processing the data with ItemProcessor into my model class. Unfortunately, the API response is an object with an array nested inside of it, which means I have to use a list referencing another class to store the data inside of it.
picture of API response
StockDTO data class:
public class StockDTO {
// We will change the field data types later when we process the data into our model.
private String from;
private String to;
private List<ProductDTO> products;
// Getters and Setters allow RestTemplate to set the data from the external rest API.
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public List<ProductDTO> getProducts() {
return products;
}
public void setProducts(List<ProductDTO> products) {
this.products = products;
}
}
ProductDTO data class (list data):
public class ProductDTO {
// We will change the field data types later when we process the data into our model.
private String sku;
private String name;
private String startDate;
// Getters and Setters allow RestTemplate to set the data from the external rest API.
public String getSku() {
return sku;
}
public void setSku(String sku) {
this.sku = sku;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
}
model class:
#Entity
public class Stock {
#Id
private long id;
private int item_from;
private int item_to;
private long sku;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public int getItem_from() {
return item_from;
}
public void setItem_from(int item_from) {
this.item_from = item_from;
}
public int getItem_to() {
return item_to;
}
public void setItem_to(int item_to) {
this.item_to = item_to;
}
public long getSku() {
return sku;
}
public void setSku(long sku) {
this.sku = sku;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ItemProcessor<StockDTO, Stock>
public class StockDataProcessor implements ItemProcessor<StockDTO, Stock> {
#Override
public Stock process(StockDTO stockDTO) throws Exception {
Stock stock = new Stock();
stock.setItem_from(Integer.parseInt(stockDTO.getFrom()));
stock.setItem_to(Integer.parseInt(stockDTO.getTo()));
// I'm only able to get the first index sku, name from the list:
stock.setSku(Long.parseLong(stockDTO.getProducts().get(0).getSku()));
stock.setName(stockDTO.getProducts().get(0).getName());
return stock;
}
}
Should I create another model class called Product so that I can create ItemProcessor<ProductDTO, Product> or can I get all the list items from ItemProcessor<StockDTO, Stock> without creating another processor? Thank you.
You could create another model class called Product and modify the Stock class to include a List and modify your ItemProcessor to populate the list of Product in the Stock class.
Alternatively, you could make your ItemProcessor return a List instead of just a single Stock. Your ItemWriter would then need to process a List<List>.

Best way to implement Table Per Hierarchy Inheritance in EF Core, ASP.NET Core MVC

During the development of my website I've decided to use a base class and derive 2 others from that.
My base class is
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gendre { get; set; }
public string CityOfBirth { get; set; }
public string ProvinceOfBirth { get; set; }
public string FiscalCode { get; set; }
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public DateTime DateOfBirth { get; set; }
public Address Address { get; set; }
public string AdditionaInfos { get; set; }
public string CountryOfBirth { get; set; }
}
Please note that I did NOT use any ID in my base class. Perhaps already a mistake. This is due to the fact that I have added the base class in a second step and I had assigned already before the IDs to the derived classes.
The other derived classes are:
public class Loaner : Person
{
public int ID { get; set; }
public int AID { get; set; }
public ICollection<A> A{ get; set; }
// user ID from AspNetUser table
public string OwnerID { get; set; }
}
and
public class Client : Person
{
public int ID { get; set; }
public string TypeOfLocator { get; set; }
public bool IsRegistered { get; set; } = false;
public bool TakeDataFromRegistration { get; set; } = false;
public bool WantsToBeContactedByEmail { get; set; } = false;
[DataType(DataType.EmailAddress)]
public string EMailAddress { get; set; }
}
My DbContext looks like that:
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
public DbSet<Client> Clients { get; set; }
public DbSet<Loaner> Loaners { get; set; }
public DbSet<Address> Address{ get; set; }
}
Now, how can I best implemet TPH, knowing that I do not have an ID in my base class?
My problem is that the IDs of the derived classes are already extensively used in the rest of my website.
I had a look here, but this approach requires having the ID on the base class.
Do I really have to Create and customize the migration code? Or is it sufficient to use fluent API like described here?
Any help is appreciated.

How to raise an event in a test that uses Moq?

Here is part of code implementation in parent class:
handler.FooUpdateDelegate += FooUpdate(OnFooUpdate);
protected abstract void OnFooUpdate(ref IBoo boo, string s);
I have in test method mocked handler:
Mock<IHandler> mHandler = mockFactory.Create<IHandler>();
This...
mHandler.Raise(x => x.FooUpdateDelegate += null, boo, s);
...is not working. It says:
System.ArgumentException : Could not locate event for attach or detach method Void set_FooUpdateDelegate(FooUpdate).
I want to raise OnFooUpdate so it triggers the code to be tested in child class.
Question: How can I raise delegate (not common event handler) with Moq?
If I missed the point completely, please enligten me.
It looks like you are trying to raise a delegate rather than an event. Is this so?
Is your code along the lines of this?
public delegate void FooUpdateDelegate(ref int first, string second);
public class MyClass {
public FooUpdateDelegate FooUpdateDelegate { get; set; }
}
public class MyWrapperClass {
public MyWrapperClass(MyClass myclass) {
myclass.FooUpdateDelegate += HandleFooUpdate;
}
public string Output { get; private set; }
private void HandleFooUpdate(ref int i, string s) {
Output = s;
}
}
If so, then you can directly invoke the myClass FooUpdateDelegate like so
[TestMethod]
public void MockingNonStandardDelegate() {
var mockMyClass = new Mock<MyClass>();
var wrapper = new MyWrapperClass(mockMyClass.Object);
int z = 19;
mockMyClass.Object.FooUpdateDelegate(ref z, "ABC");
Assert.AreEqual("ABC", wrapper.Output);
}
EDIT: Adding version using interface
public interface IMyClass
{
FooUpdateDelegate FooUpdateDelegate { get; set; }
}
public class MyClass : IMyClass {
public FooUpdateDelegate FooUpdateDelegate { get; set; }
}
public class MyWrapperClass {
public MyWrapperClass(IMyClass myclass) {
myclass.FooUpdateDelegate += HandleFooUpdate;
}
public string Output { get; private set; }
private void HandleFooUpdate(ref int i, string s) {
Output = s;
}
}
[TestMethod]
public void MockingNonStandardDelegate()
{
var mockMyClass = new Mock<IMyClass>();
// Test fails with a Null Reference exception if we do not set up
// the delegate property.
// Can also use
// mockMyClass.SetupProperty(m => m.FooUpdateDelegate);
mockMyClass.SetupAllProperties();
var wrapper = new MyWrapperClass(mockMyClass.Object);
int z = 19;
mockMyClass.Object.FooUpdateDelegate(ref z, "ABC");
Assert.AreEqual("ABC", wrapper.Output);
}

EF FluentAPI 0..1 to * mapping

How do I map a 0..1 to * relation in EF 4.0 FluentAPI CTP5?
I keep geting this error
Because all of the properties in the Dependent Role are non-nullable,
multiplicity of the Principal Role must be '1'.
And I do not know how exactly to fix it..
My code looks like this
public class Child{
public int pID { get; set; }
public Parent Parent_Object{ get; set; }
public int Parent{ get; set; }
public Child() {
}
}
public class Parent {
public int pID { get; set; }
public List<Child> Children { get; set; }
public Parent () {
}
}
For mapping the code looks like this
modelBuilder.Entity<Child>().HasKey(c=> c.pID);
modelBuilder.Entity<Parent>().HasKey(c=> c.pID);
modelBuilder.Entity<Child>().HasOptional(c=> c.Parent_Object)
.WithMany(p => p.Children)
.HasForeignKey(p => p.Parent);
Also is it possible to have only
public Parent Parent{ get; set; }
instead of
public Parent Parent_Object{ get; set; }
public int Parent{ get; set; }
In the database the FKfield is named "Parent" not "ParentpID". In this case how should the mapping look like?
You can simply remove Foreign Key Column from the mapping and everything will work fine:
public class Child{
public int pID { get; set; }
public Parent Parent_Object{ get; set; }
public Child() { }
}
public class Parent {
public int pID { get; set; }
public List Children { get; set; }
public Parent () { }
}
public class Context : DbContext {
protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) {
modelBuilder.Entity().HasKey(c => c.pID);
modelBuilder.Entity().HasKey(c => c.pID);
modelBuilder.Entity().HasOptional(c => c.Parent_Object).WithMany(p => p.Children);
}
public DbSet Parents { get; set; }
public DbSet Childs { get; set; }
}
As an alternative, you can use the nullable int Parent property, like this:
public int? ParentId { get; set; }
In this case your initial code will be correct as well.