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

Commit 8be66a1

Browse files
committed
Add support for Master.RefTableId convention for 1:1 table references
1 parent ecd8745 commit 8be66a1

File tree

2 files changed

+133
-11
lines changed

2 files changed

+133
-11
lines changed

src/ServiceStack.OrmLite/OrmLiteReadExtensions.cs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -773,13 +773,28 @@ public static void SaveAllReferences<T>(this IDbCommand dbCmd, T instance)
773773
{
774774
var refType = fieldDef.FieldType;
775775
var refModelDef = refType.GetModelDefinition();
776-
var refField = GetRefFieldDef(modelDef, refModelDef, fieldDef.FieldType);
776+
777+
var refSelf = GetSelfRefFieldDefIfExists(modelDef, refModelDef);
777778

778779
var result = fieldDef.GetValue(instance);
780+
var refField = refSelf == null
781+
? GetRefFieldDef(modelDef, refModelDef, refType)
782+
: GetRefFieldDefIfExists(modelDef, refModelDef);
783+
779784
if (result != null)
780785
{
781-
refField.SetValueFn(result, pkValue);
786+
if (refField != null)
787+
refField.SetValueFn(result, pkValue);
788+
782789
dbCmd.CreateTypedApi(refType).Save(result);
790+
791+
//Save Self Table.RefTableId PK
792+
if (refSelf != null)
793+
{
794+
var refPkValue = refModelDef.PrimaryKey.GetValue(result);
795+
refSelf.SetValueFn(instance, refPkValue);
796+
dbCmd.Update(instance);
797+
}
783798
}
784799
}
785800
}
@@ -793,14 +808,30 @@ public static void SaveReferences<T, TRef>(this IDbCommand dbCmd, T instance, pa
793808
var refType = typeof(TRef);
794809
var refModelDef = ModelDefinition<TRef>.Definition;
795810

811+
var refSelf = GetSelfRefFieldDefIfExists(modelDef, refModelDef);
812+
796813
foreach (var oRef in refs)
797814
{
798-
var refField = GetRefFieldDef(modelDef, refModelDef, refType);
815+
var refField = refSelf == null
816+
? GetRefFieldDef(modelDef, refModelDef, refType)
817+
: GetRefFieldDefIfExists(modelDef, refModelDef);
799818

800-
refField.SetValueFn(oRef, pkValue);
819+
if (refField != null)
820+
refField.SetValueFn(oRef, pkValue);
801821
}
802822

803823
dbCmd.SaveAll(refs);
824+
825+
foreach (var oRef in refs)
826+
{
827+
//Save Self Table.RefTableId PK
828+
if (refSelf != null)
829+
{
830+
var refPkValue = refModelDef.PrimaryKey.GetValue(oRef);
831+
refSelf.SetValueFn(instance, refPkValue);
832+
dbCmd.Update(instance);
833+
}
834+
}
804835
}
805836

806837
public static void LoadReferences<T>(this IDbCommand dbCmd, T instance)
@@ -831,13 +862,28 @@ public static void LoadReferences<T>(this IDbCommand dbCmd, T instance)
831862
{
832863
var refType = fieldDef.FieldType;
833864
var refModelDef = refType.GetModelDefinition();
834-
var refField = GetRefFieldDef(modelDef, refModelDef, fieldDef.FieldType);
835865

836-
var sqlFilter = ormLiteDialectProvider.GetQuotedColumnName(refField.FieldName) + "={0}";
837-
var sql = ormLiteDialectProvider.ToSelectStatement(refType, sqlFilter, pkValue);
866+
var refSelf = GetSelfRefFieldDefIfExists(modelDef, refModelDef);
867+
var refField = refSelf == null
868+
? GetRefFieldDef(modelDef, refModelDef, refType)
869+
: GetRefFieldDefIfExists(modelDef, refModelDef);
838870

839-
var result = dbCmd.ConvertTo(refType, sql);
840-
fieldDef.SetValueFn(instance, result);
871+
if (refField != null)
872+
{
873+
var sqlFilter = ormLiteDialectProvider.GetQuotedColumnName(refField.FieldName) + "={0}";
874+
var sql = ormLiteDialectProvider.ToSelectStatement(refType, sqlFilter, pkValue);
875+
var result = dbCmd.ConvertTo(refType, sql);
876+
fieldDef.SetValueFn(instance, result);
877+
}
878+
else if (refSelf != null)
879+
{
880+
//Load Self Table.RefTableId PK
881+
var refPkValue = refSelf.GetValue(instance);
882+
var sqlFilter = ormLiteDialectProvider.GetQuotedColumnName(refModelDef.PrimaryKey.FieldName) + "={0}";
883+
var sql = ormLiteDialectProvider.ToSelectStatement(refType, sqlFilter, refPkValue);
884+
var result = dbCmd.ConvertTo(refType, sql);
885+
fieldDef.SetValueFn(instance, result);
886+
}
841887
}
842888
}
843889
}
@@ -852,10 +898,17 @@ public static FieldDefinition GetRefFieldDef(ModelDefinition modelDef, ModelDefi
852898

853899
public static FieldDefinition GetRefFieldDefIfExists(ModelDefinition modelDef, ModelDefinition refModelDef)
854900
{
855-
var refNameConvention = modelDef.ModelName + "Id";
856-
var refField = refModelDef.FieldDefinitions.FirstOrDefault(x => x.FieldName == refNameConvention)
901+
var refField = refModelDef.FieldDefinitions.FirstOrDefault(x => x.FieldName == modelDef.ModelName + "Id")
857902
?? refModelDef.FieldDefinitions.FirstOrDefault(x => x.Name == modelDef.Name + "Id");
858903
return refField;
859904
}
905+
906+
public static FieldDefinition GetSelfRefFieldDefIfExists(ModelDefinition modelDef, ModelDefinition refModelDef)
907+
{
908+
var refField = modelDef.FieldDefinitions.FirstOrDefault(x => x.FieldName == refModelDef.ModelName + "Id")
909+
?? modelDef.FieldDefinitions.FirstOrDefault(x => x.Name == refModelDef.Name + "Id");
910+
911+
return refField;
912+
}
860913
}
861914
}

tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,29 @@ public class MismatchAliasAddress
138138
public string Country { get; set; }
139139
}
140140

141+
public class SelfCustomer
142+
{
143+
[AutoIncrement]
144+
public int Id { get; set; }
145+
public string Name { get; set; }
146+
147+
public int SelfCustomerAddressId { get; set; }
148+
149+
[Reference]
150+
public SelfCustomerAddress PrimaryAddress { get; set; }
151+
}
152+
153+
public class SelfCustomerAddress
154+
{
155+
[AutoIncrement]
156+
public int Id { get; set; }
157+
public string AddressLine1 { get; set; }
158+
public string AddressLine2 { get; set; }
159+
public string City { get; set; }
160+
public string State { get; set; }
161+
public string Country { get; set; }
162+
}
163+
141164
public class LoadReferencesTests
142165
: OrmLiteTestBase
143166
{
@@ -159,6 +182,8 @@ public class LoadReferencesTests
159182
db.DropAndCreateTable<OldAliasedCustomerAddress>();
160183
db.DropAndCreateTable<MismatchAliasCustomer>();
161184
db.DropAndCreateTable<MismatchAliasAddress>();
185+
db.DropAndCreateTable<SelfCustomer>();
186+
db.DropAndCreateTable<SelfCustomerAddress>();
162187
}
163188

164189
[SetUp]
@@ -394,6 +419,50 @@ public void Can_FirstMatchingField_in_JOIN_tables_with_Aliases()
394419
Assert.That(q.FirstMatchingField("Unknown"), Is.Null);
395420
}
396421

422+
[Test]
423+
public void Can_Save_and_Load_Self_References()
424+
{
425+
var customer = new SelfCustomer
426+
{
427+
Name = "Customer 1",
428+
PrimaryAddress = new SelfCustomerAddress
429+
{
430+
AddressLine1 = "1 Humpty Street",
431+
City = "Humpty Doo",
432+
State = "Northern Territory",
433+
Country = "Australia"
434+
},
435+
};
436+
437+
db.Save(customer);
438+
439+
Assert.That(customer.Id, Is.GreaterThan(0));
440+
Assert.That(customer.SelfCustomerAddressId, Is.EqualTo(0));
441+
442+
db.SaveReferences(customer, customer.PrimaryAddress);
443+
Assert.That(customer.SelfCustomerAddressId, Is.EqualTo(customer.Id));
444+
445+
var dbCustomer = db.LoadSingleById<SelfCustomer>(customer.Id);
446+
Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null);
447+
448+
customer = new SelfCustomer
449+
{
450+
Name = "Customer 2",
451+
PrimaryAddress = new SelfCustomerAddress
452+
{
453+
AddressLine1 = "2 Humpty Street",
454+
City = "Humpty Doo",
455+
State = "Northern Territory",
456+
Country = "Australia"
457+
},
458+
};
459+
460+
db.Save(customer, references:true);
461+
Assert.That(customer.SelfCustomerAddressId, Is.EqualTo(customer.Id));
462+
463+
dbCustomer = db.LoadSingleById<SelfCustomer>(customer.Id);
464+
Assert.That(dbCustomer.PrimaryAddress, Is.Not.Null);
465+
}
397466

398467
}
399468

0 commit comments

Comments
 (0)