Skip to content
This repository has been archived by the owner on Dec 24, 2022. It is now read-only.

Commit

Permalink
Add support for Multi Self References
Browse files Browse the repository at this point in the history
  • Loading branch information
mythz committed Oct 28, 2014
1 parent 091dbd8 commit 771d1c4
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 13 deletions.
Expand Up @@ -417,7 +417,7 @@ public static async Task SaveAllReferencesAsync<T>(this IDbCommand dbCmd, T inst
var refType = fieldDef.FieldType;
var refModelDef = refType.GetModelDefinition();

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, fieldDef);

var result = fieldDef.GetValue(instance);
var refField = refSelf == null
Expand Down Expand Up @@ -451,7 +451,7 @@ public static async Task SaveAllReferencesAsync<T>(this IDbCommand dbCmd, T inst
var refType = typeof(TRef);
var refModelDef = ModelDefinition<TRef>.Definition;

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, null);

foreach (var oRef in refs)
{
Expand Down
10 changes: 6 additions & 4 deletions src/ServiceStack.OrmLite/OrmLiteReadCommandExtensions.cs
Expand Up @@ -869,11 +869,13 @@ public static FieldDefinition GetRefFieldDefIfExists(this ModelDefinition modelD
return refField;
}

public static FieldDefinition GetSelfRefFieldDefIfExists(this ModelDefinition modelDef, ModelDefinition refModelDef)
public static FieldDefinition GetSelfRefFieldDefIfExists(this ModelDefinition modelDef, ModelDefinition refModelDef, FieldDefinition fieldDef)
{
var refField = modelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == refModelDef.ModelType)
?? modelDef.FieldDefinitions.FirstOrDefault(x => x.FieldName == refModelDef.ModelName + "Id")
?? modelDef.FieldDefinitions.FirstOrDefault(x => x.Name == refModelDef.Name + "Id");
var refField = fieldDef == null ? null
: modelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == refModelDef.ModelType && x.FieldName == fieldDef.FieldName + "Id")
?? modelDef.FieldDefinitions.FirstOrDefault(x => x.ForeignKey != null && x.ForeignKey.ReferenceType == refModelDef.ModelType)
?? modelDef.FieldDefinitions.FirstOrDefault(x => x.FieldName == refModelDef.ModelName + "Id")
?? modelDef.FieldDefinitions.FirstOrDefault(x => x.Name == refModelDef.Name + "Id");

return refField;
}
Expand Down
6 changes: 3 additions & 3 deletions src/ServiceStack.OrmLite/OrmLiteWriteCommandExtensions.cs
Expand Up @@ -838,7 +838,7 @@ internal static void SaveAllReferences<T>(this IDbCommand dbCmd, T instance)
var refType = fieldDef.FieldType;
var refModelDef = refType.GetModelDefinition();

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, fieldDef);

var result = fieldDef.GetValue(instance);
var refField = refSelf == null
Expand All @@ -847,7 +847,7 @@ internal static void SaveAllReferences<T>(this IDbCommand dbCmd, T instance)

if (result != null)
{
if (refField != null)
if (refField != null)
refField.SetValueFn(result, pkValue);

dbCmd.CreateTypedApi(refType).Save(result);
Expand All @@ -872,7 +872,7 @@ internal static void SaveAllReferences<T>(this IDbCommand dbCmd, T instance)
var refType = typeof(TRef);
var refModelDef = ModelDefinition<TRef>.Definition;

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, null);

foreach (var oRef in refs)
{
Expand Down
4 changes: 2 additions & 2 deletions src/ServiceStack.OrmLite/Support/LoadList.cs
Expand Up @@ -175,7 +175,7 @@ public void SetRefField(FieldDefinition fieldDef, Type refType)
{
var refModelDef = refType.GetModelDefinition();

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, fieldDef);
var refField = refSelf == null
? modelDef.GetRefFieldDef(refModelDef, refType)
: modelDef.GetRefFieldDefIfExists(refModelDef);
Expand Down Expand Up @@ -215,7 +215,7 @@ public async Task SetRefFieldAsync(FieldDefinition fieldDef, Type refType, Cance
{
var refModelDef = refType.GetModelDefinition();

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, fieldDef);
var refField = refSelf == null
? modelDef.GetRefFieldDef(refModelDef, refType)
: modelDef.GetRefFieldDefIfExists(refModelDef);
Expand Down
4 changes: 2 additions & 2 deletions src/ServiceStack.OrmLite/Support/LoadReferences.cs
Expand Up @@ -79,7 +79,7 @@ public void SetRefField(FieldDefinition fieldDef, Type refType)
{
var refModelDef = refType.GetModelDefinition();

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, fieldDef);
var refField = refSelf == null
? modelDef.GetRefFieldDef(refModelDef, refType)
: modelDef.GetRefFieldDefIfExists(refModelDef);
Expand Down Expand Up @@ -116,7 +116,7 @@ public async Task SetRefField(FieldDefinition fieldDef, Type refType, Cancellati
{
var refModelDef = refType.GetModelDefinition();

var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef);
var refSelf = modelDef.GetSelfRefFieldDefIfExists(refModelDef, fieldDef);
var refField = refSelf == null
? modelDef.GetRefFieldDef(refModelDef, refType)
: modelDef.GetRefFieldDefIfExists(refModelDef);
Expand Down
72 changes: 72 additions & 0 deletions tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs
Expand Up @@ -163,6 +163,26 @@ public class SelfCustomerAddress
public string Country { get; set; }
}

public class MultiSelfCustomer
{
[AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }

[References(typeof(SelfCustomerAddress))]
public int? HomeAddressId { get; set; }

[References(typeof(SelfCustomerAddress))]
public int? WorkAddressId { get; set; }

[Reference]
public SelfCustomerAddress HomeAddress { get; set; }

[Reference]
public SelfCustomerAddress WorkAddress { get; set; }
}


public class LoadReferencesTests
: OrmLiteTestBase
{
Expand All @@ -186,6 +206,7 @@ public new void TestFixtureSetUp()
db.DropAndCreateTable<MismatchAliasAddress>();
db.DropAndCreateTable<SelfCustomer>();
db.DropAndCreateTable<SelfCustomerAddress>();
db.DropAndCreateTable<MultiSelfCustomer>();
}

[SetUp]
Expand Down Expand Up @@ -585,6 +606,57 @@ public void Can_load_list_of_self_references()
Assert.That(results[0].PrimaryAddress.Country, Is.EqualTo("Australia"));
}

[Test]
public void Can_support_multiple_self_references()
{
var customers = new[]
{
new MultiSelfCustomer
{
Name = "Customer 1",
HomeAddress = new SelfCustomerAddress
{
AddressLine1 = "1 Home Street",
Country = "Australia"
},
WorkAddress = new SelfCustomerAddress
{
AddressLine1 = "1 Work Street",
Country = "Australia"
},
},
new MultiSelfCustomer
{
Name = "Customer 2",
HomeAddress = new SelfCustomerAddress
{
AddressLine1 = "2 Home Park",
Country = "USA"
},
WorkAddress = new SelfCustomerAddress
{
AddressLine1 = "2 Work Park",
Country = "USA"
},
},
};

customers.Each(x =>
db.Save(x, references: true));

var results = db.LoadSelect<MultiSelfCustomer>(q =>
q.HomeAddressId != null &&
q.WorkAddressId != null);

results.PrintDump();

Assert.That(results.Count, Is.EqualTo(2));
Assert.That(results[0].HomeAddress.AddressLine1, Is.StringContaining("Home"));
Assert.That(results[0].WorkAddress.AddressLine1, Is.StringContaining("Work"));
Assert.That(results[1].HomeAddress.AddressLine1, Is.StringContaining("Home"));
Assert.That(results[1].WorkAddress.AddressLine1, Is.StringContaining("Work"));
}

}

}

0 comments on commit 771d1c4

Please sign in to comment.