Parent and Child object in SimpleRepository - subsonic

How would it work in Subsonic's SimpleReporitory if I wanted to be able to have a 1 to many relationship between objects?
Would I have to create a bridge object and then build my parent object at runtime, or is this support built in?
What I am looking for is the folowing:
Adam's Example Shop...
Public Class Shop
Private m_id As Integer
Private m_Name As String
Private m_Employees As List(Of Employee)
Public Property Id() As Integer
Get
Return m_id
End Get
Set(ByVal value As Integer)
m_id = value
End Set
End Property
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = value
End Set
End Property
Public Property Employees() As List(Of Employee)
Get
Return m_Employees
End Get
Set(ByVal value As List(Of Employee))
m_Employees = value
End Set
End Property
End Class
Public Class Employee
Private m_id As Integer
Private m_Name As String
Public Property Id() As Integer
Get
Return m_id
End Get
Set(ByVal value As Integer)
m_id = value
End Set
End Property
Public Property Name() As String
Get
Return m_Name
End Get
Set(ByVal value As String)
m_Name = value
End Set
End Property
End Class
Main bits:
Dim repo As New SimpleRepository("SubSonicObjectTest", SimpleRepositoryOptions.RunMigrations)
Dim emplyee1 As New Employee
emplyee1.Name = "Martin"
Dim emplyee2 As New Employee
emplyee2.Name = "Adam"
Dim shop As New Shop
shop.Name = "Sub Sonic Store"
shop.Employees = New List(Of Employee)
shop.Employees.Add(emplyee1)
shop.Employees.Add(emplyee2)
repo.Add(Of Shop)(shop)
I think this should create 3 tables:
Shops
Employees
ShopsToEmployees (or some other naming convention)
But I only get a Channels table!

I'm updating the SimpleRepo stuff currently to automatically create joined tables based on collections. Not easy to determine many/many vs 1/many - but I have some ideas :).

To create a one to many relationship you just have to create the object model, SubSonic should do the rest for you e.g.
public class Shop
{
public int Id { get; set; }
public String Name { get; set; }
public List<Employee> Employees { get; set; }
}
public class Employee
{
public int Id { get; set; }
public String Name { get; set; }
}
EDIT: This should generate two tables when you run a migration not 3. The 3 three tables you describe in your question would represent a many to many relationship. Also in your example you're not saving your Employees, SubSonic does not cascade saves so you'll need to save your Shop then add the Employees to it and BatchSave the Employees.

Related

Does poi-objectmapper maps the excel sheet to a nested object? If so, what should be done?

I'm trying to map the excel sheet to pojo using poi-object-mapper. It is working fine if the excel header name matches with the property name. But not working on a nested object.
I have a Employee Object that has a address object. How to map the street name in excel sheet to address.streetname?
public class Employee {
//#SheetColumn("Name")
private String name;
//#SheetColumn("Age")
private Integer age;
private Address address;
}

VBA Implements / Inheritance

I'm having a hard time understanding and working with Implements and I'm failing to see why this is of any use if Inheritance isn't supported with VBA.
I'm testing the code below and I keep getting the error:
Compile Error:
Object module needs to implement '~' for interface '~'
Interface: ITransmission
Option Explicit
Public pVENDOR As String
Public Property Get VENDOR() As String
End Property
Public Property Let VENDOR(ByVal value As String)
End Property
Base Class: cASN
Option Explicit
Implements ITransmission
Private Property Let ITransmission_pVENDOR(ByVal value As String)
pVENDOR = value
End Property
Private Property Get ITransmission_pVENDOR() As String
ITransmission_pVENDOR = pVENDOR
End Property
Unit Test Method: mUnitTesting
Private Sub Test_cASN()
Dim foo As cASN
Set foo = New cASN
foo.VENDOR = "Test"
End Sub
Still very new to Implements and it is something I want to learn, and I've done a fair amount of research into it.
Question 1:
Why am I getting an error message when I try to unit test this?
Question 2:
What is the real benefit here, if inheritance isn't supported?
You implement pVENDOR but not the two VENDOR properties.
I'm assuming you want the interface to be a get/let of the VENDOR property.
Your Public pVENDOR As String looks like a backing field for this property, as an Interface cannot include an implementation then its not needed.
The Interface should look like:
Public Property Get VENDOR() As String
End Property
Public Property Let VENDOR(ByVal value As String)
End Property
Then when you implement it:
Implements ITransmission
Private pVENDOR As String '// local implementation detail
Public Property Let ITransmission_VENDOR(ByVal value As String)
pVENDOR = value
End Property
Public Property Get ITransmission_VENDOR() As String
ITransmission_VENDOR = pVENDOR
End Property
And to test:
Private Sub Test_cASN()
Dim foo As cASN
Set foo = New cASN
foo.ITransmission_VENDOR = "Test"
End Sub
What is the real benefit here
How will I know when to create an interface?
The point of an Interface

How to loop through set values in Object property class in C#?

I have this property class like:
public class ABC{
public string a {get;set;}
public int? b {get;set;}
public string c {get;set;}
public int? d {get;set;}
public int? e {get;set;}
public int? f {get;set;}
}
string lineabc = "8004CF::JAI2310:0:5:0";
string[] splitrow = lineabc.Split(':');
I have to loop through set all the values in this object property class, the values which i want to set in the object class by splitrow array value.
i don't want to set values one by one in class object property like :
ABC.a = splitrow[0];

Map a flat structure to an object with AutoMapper?

The data being returned from a stored procedure has 3 columns of repeating data:
Name | Address | PhoneNumber | UniqueCol1 | UniqueCol2
Ideally I want my model to show that there is repeated data by only storing the values once and have a collection of the unique data.
public class MyViewModel
{
public string Name {get;set;}
public string Address {get;set;}
public string PhoneNumber {get;set;}
public List<MyModel> UniqueData {get;set;}
public class MyModel
{
public string UniqueCol1 {get;set;}
public string UniqueCol2 {get;set;}
}
}
This means I want to map a collection of results to a single object of MyViewModel:
return Mapper.Map<List<StoredProcedureObject>, MyViewModel>(result);
This is where I get my error as I assume I have some configuration that I need to do:
Mapping types:
List`1 -> MyViewModel
Any ideas on the missing step to get this to work?
Automapper is only able to flatten your structure into something simpler. But it's not possible to map a simple class to something more specific.
I would suggest to take only the first entry in your table to fill your base fields like Name, Address, PhoneNumber and iterate over your results to fill your UniqueData List.
I don't see an easier way, because with each possible mapping and without using seperate loops you will get your base data multiple times.
If you don't mind to use another tool, maybe you will have a look at ValueInjecter. I heard you can use this tool for two-way-mappings.

Automapper with a base class enumeration property

Is there any way to get this to work? Here's a simplified/contrived illustration of my issue (Pardon my wordy VB):
Domain Model Classes
Public Class Car
Public Property Id As Integer
Public Property Seats As IEnumerable(Of Seat)
End Class
Public MustInherit Class Seat
End Class
Public Class StandardSeat
Inherits Seat
Public Property Manufacturer As String
End Class
Public Class CustomSeat
Inherits Seat
Public Property Installer As String
End Class
View Model Classes
Public Class CarModel
Public Property Id As String
Public Property Seats As IEnumerable(Of SeatModel)
End Class
Public Class SeatModel
Public Property Manufacturer As String
Public Property Installer As String
End Class
Mapping and Test Code
<Test()> Public Sub Test()
Mapper.CreateMap(Of Car, CarModel)()
Mapper.CreateMap(Of Seat, SeatModel)() _
.ForMember("Manufacturer", Sub(cfg) cfg.Ignore()) _
.ForMember("Installer", Sub(cfg) cfg.Ignore())
Mapper.CreateMap(Of StandardSeat, SeatModel)() _
.ForMember("Installer", Sub(cfg) cfg.Ignore())
Mapper.CreateMap(Of CustomSeat, SeatModel)() _
.ForMember("Manufacturer", Sub(cfg) cfg.Ignore())
Mapper.AssertConfigurationIsValid()
Dim car As New Car With {.Id = 4}
car.Seats = New Seat() {
New StandardSeat With {.Manufacturer = "Honda"},
New CustomSeat With {.Installer = "Napa"}}
Dim model = Mapper.Map(Of Car, CarModel)(car)
model.Id.ShouldEqual("4")
model.Seats.Count().ShouldEqual(2)
' These next two assertions fail.
model.Seats.First().Manufacturer.ShouldEqual("Honda")
model.Seats.Last().Installer.ShouldEqual("Napa")
End Sub
Instead of doing this, I'd map to a parallel inheritance hierarchy on the ViewModel side. Create a SeatModel, StandardSeatModel and a CustomSeatModel. You would then use the Include() configuration option to link the Seat -> SeatModel mapping configuration to the mapping configurations to StandardSeat -> StandardSeatModel and the other.
This way, you don't need all the Ignore() s and whatnot. If you still want to flatten your original model, you'll still need to include the Include() configuration on the Seat -> SeatModel piece.

Resources