JSON convert Ignore Empty Object C# - object

I try to ignore an empty object on my Json
this is my Json :
{
"custNmae": "test n test p",
"firstName": "test n",
"lastName": "test p",
"updateDate": "2018-12-28T16:25:25Z",
"tutor": {}
}
Does any one have a idea how to resolve this ?
Please let me know !!!!

private class CustomerB2C
{
public string custName = "";
public string firstName = "";
public string lastName = "";
public DateTime updateDate = DateTime.MinValue;
public Tutor tutor = null;
}
private class Tutor
{
public string tutorName = "";
}
private static void test()
{
CustomerB2C customerB2C = new CustomerB2C();
customerB2C.custName = "Mike Smith";
customerB2C.firstName = "Mike";
customerB2C.lastName = "Smith";
customerB2C.updateDate = DateTime.Now;
customerB2C.tutor = null; //is already null, setting to null here for demonstration purposes
string json1 = JsonConvert.SerializeObject(customerB2C);
string json2 = JsonConvert.SerializeObject(customerB2C, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
}

Related

Using filter design pattern for dynamically creating a filter criteria

I have a requirement to search a collection of objects (say, reservations) based on one or more of the following search criteria. I'm planning to use the filter pattern to implement this.
Search options: firstname, lastname, phone, email
The requirement is - if the user specifies only the fistname filter, use only firstname to filter. If the user specifies both firstname and phone, use both (and criteria) to filter. If all 4 options are specified use all 4.
I've created the classes for all 4 search criterion. I'm in doubt as to how to use it. For example,
ISearchCriteria searchCriteria;
if(firstName != null)
{
searchCriteria= new FirstNameSearchCriteria(CurrentClient);
}
if(lastName!= null)
{
//what do I do here? I have an AndCriteria class which accepts two ISearchCriteria objects. How do I use it?
}
What's the correct way to handle this search scenario?
You should design the solution of your problem statement by using Intercepting Filter Pattern.
Below is the code using with Intercepting Filter Pattern:
public class Person
{
public String FirstName { get; set; }
public String LastName { get; set; }
public String Phone { get; set; }
public String Email { get; set; }
}
public interface ICriteria
{
List<Person> MeetCriteria(List<Person> persons);
}
public class CriteriaFirstName : ICriteria
{
private string searchCriteria;
public CriteriaFirstName(string searchCriteria)
{
this.searchCriteria = searchCriteria;
}
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> personsData = new List<Person>();
foreach (var item in persons)
{
if (item.FirstName.ToUpper().Equals(searchCriteria.ToUpper()))
{
personsData.Add(item);
}
}
return personsData;
}
public class CriteriaLastName : ICriteria
{
private string searchCriteria;
public CriteriaLastName(string searchCriteria)
{
this.searchCriteria = searchCriteria;
}
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> personsData = new List<Person>();
foreach (var item in persons)
{
if (item.LastName.ToUpper().Equals(searchCriteria.ToUpper()))
{
personsData.Add(item);
}
}
return personsData;
}
}
public class CriteriaLastPhone : ICriteria
{
private string searchCriteria;
CriteriaLastPhone(string searchCriteria)
{
this.searchCriteria = searchCriteria;
}
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> personsData = new List<Person>();
foreach (var item in persons)
{
if (item.Phone.ToUpper().Equals(searchCriteria.ToUpper()))
{
personsData.Add(item);
}
}
return personsData;
}
}
public class CriteriaEmail : ICriteria
{
private string searchCriteria;
public CriteriaEmail(string searchCriteria)
{
this.searchCriteria = searchCriteria;
}
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> personsData = new List<Person>();
foreach (var item in persons)
{
if (item.Email.ToUpper().Equals(searchCriteria.ToUpper()))
{
personsData.Add(item);
}
}
return personsData;
}
}
public class AndCriteria : ICriteria
{
private ICriteria criteria;
private ICriteria otherCriteria;
public AndCriteria(ICriteria criteria, ICriteria otherCriteria)
{
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> firstCriteriaPersons = criteria.MeetCriteria(persons);
return otherCriteria.MeetCriteria(firstCriteriaPersons);
}
}
public class OrCriteria : ICriteria
{
private ICriteria criteria;
private ICriteria otherCriteria;
public OrCriteria(ICriteria criteria, ICriteria otherCriteria)
{
this.criteria = criteria;
this.otherCriteria = otherCriteria;
}
public List<Person> MeetCriteria(List<Person> persons)
{
List<Person> firstCriteriaItems = criteria.MeetCriteria(persons);
List<Person> otherCriteriaItems = otherCriteria.MeetCriteria(persons);
foreach (var otherItems in otherCriteriaItems)
{
if (!firstCriteriaItems.Contains(otherItems))
{
firstCriteriaItems.Add(otherItems);
}
}
return firstCriteriaItems;
}
}
Driver Code:
class Program
{
static void Main(string[] args)
{
List<Person> persons = new List<Person>();
persons.Add(new Person { FirstName = "Robert", LastName = "kerry", Phone = "1234", Email = "cddd#xyz.com"});
persons.Add(new Person { FirstName = "Robert", LastName = "Sam", Phone = "1234", Email = "sam#xyz.com" });
persons.Add(new Person { FirstName = "Jon", LastName = "Kam", Phone = "1234", Email = "john#xyz.com" });
Console.WriteLine("---Search by First and Last Name----");
ICriteria firstName = new CriteriaFirstName("Robert");
ICriteria lastName = new CriteriaLastName("Kerry");
ICriteria fullName = new AndCriteria(firstName, lastName);
var searchedData = fullName.MeetCriteria(persons);
//Search by First and last name (And criteria)
foreach (var person in searchedData)
{
Console.WriteLine(person.FirstName);
Console.WriteLine(person.LastName);
Console.WriteLine(person.Phone);
}
//Search by first name and email. (And Criteria)
firstName = new CriteriaFirstName("Robert");
var email = new CriteriaEmail("sam#xyz.com");
fullName = new AndCriteria(firstName, email);
searchedData = fullName.MeetCriteria(persons);
foreach (var person in searchedData)
{
Console.WriteLine(person.FirstName);
Console.WriteLine(person.LastName);
Console.WriteLine(person.Phone);
}
Console.WriteLine("---Search by First Name Only----");
firstName = new CriteriaFirstName("Robert");
searchedData = firstName.MeetCriteria(persons);
foreach (var person in searchedData)
{
Console.WriteLine(person.FirstName);
Console.WriteLine(person.LastName);
Console.WriteLine(person.Phone);
}
Console.WriteLine("---Search by First Name or email ----");
//Search by first name . (or Criteria)
firstName = new CriteriaFirstName("Robert");
email = new CriteriaEmail("john#xyz.com");
fullName = new OrCriteria(firstName, email);
searchedData = fullName.MeetCriteria(persons);
foreach (var person in searchedData)
{
Console.WriteLine(person.FirstName);
Console.WriteLine(person.LastName);
Console.WriteLine(person.Phone);
}
Console.ReadKey();
}
}

C#: how to display the employee names with lowest salary

I have to create an appropriate GUI to enter information for at least 10 employee. for each employee i have to enter the following information. employee ID, employee first name, employee last name and yearly salary. besides i have to check for the correctness of the input data. in addition i need to create a separate class EMPLOYEE, containing employee information: employee ID, first name , last name and yearly salary. the class should have constructors properties and methods. all the employee information has to be stored in a array of type employee. after reading form GUI the information about particular employee , also create an object of class employee(element of the array) with the relevant constructor. the user would like to be able to find the employee with lowest yearly salary despite of having more than one employee with lowest yearly salary. and display information about them. user should be provided with appropriate GUI to display the required information.
i need to assure including in my program appropriate code for handling exceptions and also methods where appropriate.
here is the class employee:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Project_employee
{
class Employee
{
private int employeeID;
private string fullName;
private string lastName;
private double salary;
public Employee()
{
employeeID = 0;
fullName = "";
lastName = "";
salary = 0.0;
}
public Employee(int empIDValue, string fullNameVal, string lastNameVal)
{
employeeID = empIDValue;
fullName = fullNameVal;
lastName = lastNameVal;
salary = 0.0;
}
public Employee(int empIDValue, string fullNameVal, string lastNameVal, double salaryValue)
{
employeeID = empIDValue;
fullName = fullNameVal;
lastName = lastNameVal;
salary = salaryValue;
}
public int EmployeeIDNum
{
get
{
return employeeID;
}
set
{
employeeID = value;
}
}
public string FullName
{
get
{
return fullName;
}
set
{
fullName = value;
}
}
public int Getinfo
{
get
{
return employeeID;
}
set
{
employeeID = value;
}
}
public string employeeInformationToString()
{
// employeeID = Convert.ToInt32(this.textBox1.Text);
return (Convert.ToString(employeeID) + " " + fullName + " " + lastName + " " + Convert.ToString(salary));
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Project_employee
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void Searchbtn_Click(object sender, EventArgs e)
{
employee[0] = new Employee();
employee[1] = new Employee(17433, "Adrian", "Smith", 8000.00);
employee[2] = new Employee(17434, "Stephen", "Rad", 9000.00);
employee[3] = new Employee(17435, "Jesse", "Harris", 800.00);
employee[4] = new Employee(17436, "jonatan", "Morris", 9500.00);
employee[5] = new Employee(17437, "Morgen", "Freeman", 12000.00);
employee[6] = new Employee(17438, "Leory", "Gomez", 10200.00);
employee[7] = new Employee(17439, "Michael", "Brown", 9000.00);
employee[8] = new Employee(17440, "Andrew", "White", 3500.00);
employee[9] = new Employee(17441, "Maria", "Carson", 12000.00);
//employee[10] = new Employee(17442, "Mark", "Jonson", 17000.00);
for(int i = 0; i < 10; i++)
{
string employeeString = employee[i].employeeInformationToString() + "\r\n";
richTextBox1.AppendText(employeeString);
}
}
Employee[] employee = new Employee[10];
private void getinfibtn_Click(object sender, EventArgs e)
{
Find();
}
private void Find()
{
}
}
}
My question is:
How the user can find the employee with the lowest yearly salary. i have to make sure that there can be more than one employee with lowest yearly salary and display the information about them. providing the user with an appropriate GUI (e.g a message box) to display the required information with including appropriate code for handling exceptions and also use methods where appropriate?
You need to make your class Employee to implement the IComparable interface, then compare the objects against the salary and in the other class sort the array...
Example:
public class Employee :IComparable<Employee>
{
private int employeeID;
private string fullName;
private string lastName;
private double salary;
public int CompareTo(Employee other)
{
return salary.CompareTo(other.salary);
}
}
private void Find()
{
Array.Sort(employee); // after this Employee is sorted
employee[0];
or
employee[9];
}
this will give a list of lowest salary emplyees
employee.Add(new Employee(17434, "Stephen", "Rad", 9000.00));
employee.Add(new Employee(17435, "Jesse", "Harris", 800.00));
employee.Add(new Employee(17436, "jonatan", "Morris", 9500.00));
var c = employee.OrderBy(i => i.salary).ToList();
var e = employee.Where(i => Math.Abs(i.salary - c[0].salary) < 1).ToList();
Modified you code a little bit
class Employee
{
private int employeeID;
private string fullName;
private string lastName;
private double salary;
public double Salary
{
get
{
return salary;
}
set
{
salary = value;
}
}
//public Employee()
//{
// employeeID = 0;
// fullName = "";
// lastName = "";
// salary = 0.0;
//}
//public Employee(int empIDValue, string fullNameVal, string lastNameVal)
//{
// employeeID = empIDValue;
// fullName = fullNameVal;
// lastName = lastNameVal;
// salary = 0.0;
//}
public Employee(int empIDValue, string fullNameVal, string lastNameVal, double salaryValue)
{
employeeID = empIDValue;
fullName = fullNameVal;
lastName = lastNameVal;
salary = salaryValue;
}
public int EmployeeIDNum
{
get
{
return employeeID;
}
set
{
employeeID = value;
}
}
public string FullName
{
get
{
return fullName;
}
set
{
fullName = value;
}
}
public int Getinfo
{
get
{
return employeeID;
}
set
{
employeeID = value;
}
}
public string employeeInformationToString()
{
// employeeID = Convert.ToInt32(this.textBox1.Text);
return (Convert.ToString(employeeID) + " " + fullName + " " + lastName + " " + Convert.ToString(salary));
}
}
and to get min values in list
var minEmpSalarylist = employee.Where(x => x.Salary == employee.Min(y => y.Salary)).ToList();
If default constructor is present then all minEmpSalarylist become initialized with default constructor.
and
employee[0] = new Employee();
to change it to
employee[0] = new Employee(17433, "XXX", "YYY", 8000.00);

ServiceStack 'ExcludePropertyReferences' dynamically if decorate with datamember attribute

I want to ignore some properties from my Object during run time. The properties are decorated with data member attribute (Without data member attribute excludepropertyreferencces is working fine). Can you please provide some insight? Thanks
Question : HOW TO EXCLUDE PROPERTIES AT RUN TIME, IF THEY ARE DECORATE WITH DATAMEMBER ATTRIBUTE ?
ServiceStack , ExcludePropertyReferences
var model = new Model {
FirstName = "First Name",
LastName = "Last Name",
Children = new List<ModelChild>{
new ModelChild { ChildFirstName = "ChildFirstName 1", ChildLastName = "ChildLastName 1" },
new ModelChild { ChildFirstName = "ChildFirstName 2", ChildLastName = "ChildLastName 2" }
}
};
var model1 = new Model1 {
FirstName = "First Name",
LastName = "Last Name",
Children = new List<Model1Child>{
new Model1Child { ChildFirstName = "ChildFirstName 1", ChildLastName = "ChildLastName 1" },
new Model1Child { ChildFirstName = "ChildFirstName 2", ChildLastName = "ChildLastName 2" }
}
};
Console.WriteLine("Properties won't get ignored because the Model is decorated with Serialization Attributes");
using(MemoryStream stream = new MemoryStream())
using (var jsConfig = JsConfig.BeginScope()) {
jsConfig.ExcludeTypeInfo = true;
jsConfig.ExcludePropertyReferences = new [] { "Model.LastName", "ModelChild.ChildLastName" }.ToArray();
JsonSerializer.SerializeToStream(model, model.GetType(), stream);
LINQPad.Extensions.Dump(System.Text.Encoding.Default.GetString(stream.ToArray()));
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("Properties will get ignored because the Model is not decorated with Serialization Attributes");
using(MemoryStream stream = new MemoryStream())
using (var jsConfig = JsConfig.BeginScope()) {
jsConfig.ExcludeTypeInfo = true;
jsConfig.ExcludePropertyReferences = new [] { "Model1.LastName", "Model1Child.ChildLastName" }.ToArray();
JsonSerializer.SerializeToStream(model1, model1.GetType(), stream);
LINQPad.Extensions.Dump(System.Text.Encoding.Default.GetString(stream.ToArray()));
}
// Define other methods and classes here
[DataContract()]
public class Model {
[DataMember(Name = "first_name",EmitDefaultValue = false )]
public string FirstName { get; set; }
[DataMember(Name = "last_name")]
public string LastName { get; set; }
[DataMember(Name = "collections")]
public List<ModelChild> Children { get; set; }
}
[DataContract()]
public class ModelChild {
[DataMember(Name = "child_first_name")]
public string ChildFirstName { get; set; }
[DataMember(Name = "child_last_name")]
public string ChildLastName { get; set; }
}
public class Model1 {
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Model1Child> Children { get; set; }
}
public class Model1Child {
public string ChildFirstName { get; set; }
public string ChildLastName { get; set; }
}

Servicestack ORMLite update child collection

I can see you can do stuff like this in ORMLite:
var customer = new Customer {
Name = "Customer 1",
PrimaryAddress = new CustomerAddress {
AddressLine1 = "1 Australia Street",
Country = "Australia"
},
Orders = new[] {
new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m },
new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m },
}.ToList(),
};
db.Save(customer, references:true);
But what about updating child collections?
How is this done?
To expand on this.
I have a UserAccount class and an Image class internal to UserAccount:
public class UserAccount
{
[AutoIncrement]
public int Id {
get ;
set;
}
public UserAccount()
{
Images = new List<UserImage>();
}
public List<UserImage> Images { get; protected set; }
public UserImage Image { get; set; }
public class UserImage
{
public UserImage()
{
Created = DateTime.Now;
}
public UserImage(string name)
{
Value = name;
Created = DateTime.Now;
}
public string Value { get; set; }
}
}
Doing this:
var fullImage = new UserAccount.UserImage(newImageUrl);
fullImage.IsDefault = true;
user.Image = fullImage;
db.Update (fullImage);
Doesn't work.
Doing this:
var fullImage = new UserAccount.UserImage(newImageUrl);
fullImage.IsDefault = true;
user.Images.Add(fullImage);
db.Update (fullImage);
Doesn't work...
Also doing the same but having image as a seperate entity with it's own ID and setting reference on the parent class doesn't work?
I think this is the way:
var image = new UserImage(newImageUrl);
image.IsDefault = true;
db.Save (image);
var images = user.Images;
images.Add (image);
db.Update (new UserAccount{Id = user.Id, Image = image, Images = images});
I hope I am wrong because that is so ugly :/
[UPDATE]
I have it looking like this now which is much nicer:
db.UpdateOnly (user,
onlyFields: a=> new { a.Image, a.Images},
where: ua => ua.Id == user.Id);

ServiceStack OrmLite How can I achieve automatic setting of foreign key/related properties?

I have created the following example to test Foreign Keys and up to this point, it works well. What I would like to be able to do, is use this framework that I built to set the property of the relationship and have it Save the child object when the Parent is saved and automatically set the PrimaryKey and Foreign Key.
The DataManager class exposes the Connection
public class DataManager
{
DataManager()
{
OrmLiteConfig.DialectProvider = SqliteDialect.Provider;
ConnectionString = SqliteFileDb;
updateTables();
}
private void updateTables()
{
using (var dbConn = OpenDbConnection())
{
dbConn.DropAndCreateTable<Person>();
dbConn.DropAndCreateTable<PhoneNumber>();
}
}
public static string SqliteFileDb = "~/App_Data/db.sqlite".MapAbsolutePath();
private static DataManager manager;
public static DataManager Manager {
get
{
if (manager == null)
manager = new DataManager();
return manager;
}
}
public IDbConnection InMemoryDbConnection { get; set; }
public IDbConnection OpenDbConnection(string connString = null)
{
connString = ConnectionString;
return connString.OpenDbConnection();
}
protected virtual string ConnectionString { get; set; }
protected virtual string GetFileConnectionString()
{
var connectionString = SqliteFileDb;
return connectionString;
}
}
These are my POCO's with the BaseClass used to Achieve my results:
public class Person : LiteBase
{
[AutoIncrement]
[PrimaryKey]
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
private List<PhoneNumber> numbers;
public List<PhoneNumber> PhoneNumbers {
get
{
if (numbers == null)
numbers = GetList<PhoneNumber>(p => p.Person == Id);
return numbers;
}
}
}
public class PhoneNumber
{
public string Number { get; set; }
public string Description { get; set; }
[AutoIncrement]
[PrimaryKey]
public int Id { get; set; }
[References(typeof (Person))]
public int Person { get; set; }
public void AddPerson(Person person)
{
Person = person.Id;
}
}
public class LiteBase:INotifyPropertyChanged
{
public List<T> GetList<T>(Expression< Func<T,bool>> thefunction) where T : new()
{
var objects = new List<T>();
using (var conn = Data.DataManager.Manager.OpenDbConnection())
{
objects = conn.Where<T>(thefunction);
}
return objects;
}
public T GetItem<T>(Expression<Func<T, bool>> thefunction) where T : new()
{
T obj = new T();
using (var conn = Data.DataManager.Manager.OpenDbConnection())
{
obj = conn.Where<T>(thefunction).FirstOrDefault<T>();
}
return obj;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
Simple Class to Create Person and PhoneNumber objects
public class PersonManager
{
public void CreatePerson(string name, string surname, string number)
{
using (var conn = DataManager.Manager.OpenDbConnection())
{
var pnum = new PhoneNumber { Number = number };
var person = new Person
{
Name=name,
Surname = surname,
};
conn.Save<Person>(person);
var id = conn.GetLastInsertId();
person.Id = (int)id;
pnum.AddPerson(person);
conn.Save<PhoneNumber>(pnum);
}
}
public List<Person> GetPeople()
{
List<Person> people;
using (var conn = DataManager.Manager.OpenDbConnection())
{
people = conn.Select<Person>();
}
return people;
}
public List<PhoneNumber> GetNumbers()
{
List<PhoneNumber> numbers;
using (var conn = DataManager.Manager.OpenDbConnection())
{
numbers = conn.Select<PhoneNumber>();
}
return numbers;
}
}
And here is the usage:
var manager = new PersonManager();
manager.CreatePerson("John", "Doe", "12345679");
manager.CreatePerson("Jack", "Smith", "12345679");
manager.CreatePerson("Peter", "Jones", "12345679");
manager.CreatePerson("Dan", "Hardy", "12345679");
var people = manager.GetPeople();
var numbers = manager.GetNumbers();
for (int i = 0; i < people.Count; i++)
{
Console.WriteLine("{0} {1} {2}",
people[i].Name,people[i].Surname,people[i].Id);
}
for (int n = 0; n < numbers.Count; n++)
{
Console.WriteLine("PN: {0} {1}",
numbers[n].Number,numbers[n].Person);
}
for (int p = 0; p < people.Count; p++)
{
var person = people[p];
Console.WriteLine("{0}: {1} {2} {3}",
person.Id,person.Name,person.Surname,person.GetItem<PhoneNumber>(x=>x.Person==person.Id).Number);
}
The output is as I expected :
John Doe 1
Jack Smith 2
Peter Jones 3
Dan Hardy 4
PN: 12345679 1
PN: 12345679 2
PN: 12345679 3
PN: 12345679 4
1: John Doe 12345679
2: Jack Smith 12345679
3: Peter Jones 12345679
4: Dan Hardy 12345679
What I really would like to be able to do is the following:
var john = new Person
{
Name = "John",
Surname = "Smith",
PhoneNumber = new PhoneNumber { Number = "123456789" }
};
conn.Save<Person>(john);
var number = john.PhoneNumber.Number
Is this at all possible?
By default OrmLite v3 blobs all complex types properties in a string field and you need to explicitly set all references.
In the next major v4 release (ETA late Nov 2013), OrmLite adds some support for external references with the [Reference] attribute, which lets you tell OrmLite these properties should be stored in an external table and not blobbed, e.g:
public class Customer
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
[Reference]
public CustomerAddress PrimaryAddress { get; set; }
[Reference]
public List<Order> Orders { get; set; }
}
This will allow you to call db.SaveReferences() to save the reference properties, e.g:
var customer = new Customer
{
Name = "Customer 1",
PrimaryAddress = new CustomerAddress {
AddressLine1 = "1 Humpty Street",
City = "Humpty Doo",
State = "Northern Territory",
Country = "Australia"
},
Orders = new[] {
new Order { LineItem = "Line 1", Qty = 1, Cost = 1.99m },
new Order { LineItem = "Line 2", Qty = 2, Cost = 2.99m },
}.ToList(),
};
Assert.That(customer.Id, Is.EqualTo(0)); //Id is not saved yet
//Inserts customer, populates auto-incrementing customer.Id
//Specify `references:true` to populate the ForeignKey ids and
//save the related rows as well, e.g:
db.Save(customer, references:true);
Assert.That(customer.Id, Is.GreaterThan(0));
Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(customer.Id));
Assert.That(customer.Orders.All(x => x.CustomerId == customer.Id));
Saving References manually
For more fine-grained control you can also choose which references you want to save, e.g:
db.Save(customer); //Doesn't save related rows
//1:1 PrimaryAddress Reference not saved yet
Assert.That(customer.PrimaryAddress.CustomerId, Is.EqualTo(0));
//1:1 PrimaryAddress Reference saved and ForeignKey id populated
db.SaveReferences(customer, customer.PrimaryAddress);
//1:Many Orders References saved and ForeignKey ids populated
db.SaveReferences(customer, customer.Orders);
Loading all related rows with the entity
You can then load the master row and all its references with db.LoadSingleById, e.g:
var dbCustomer = db.LoadSingleById<Customer>(customer.Id);
dbCustomer.PrintDump();
Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null);
Assert.That(dbCustomer.Orders.Count, Is.EqualTo(2));

Resources