Skip to content

Commit 4c26cbb

Browse files
Merge pull request MikaelEliasson#49 from MikaelEliasson/release101
Bug fix release 1.0.1
2 parents dc93f6f + d780b31 commit 4c26cbb

File tree

11 files changed

+212
-15
lines changed

11 files changed

+212
-15
lines changed

EntityFramework.Utilities/EntityFramework.Utilities/EFBatchOperation.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,19 +160,10 @@ public void UpdateAll<TEntity>(IEnumerable<TEntity> items, Action<UpdateSpecific
160160
.Select(p => new ColumnMapping {
161161
NameInDatabase = p.ColumnName,
162162
NameOnObject = p.PropertyName,
163-
DataType = p.DataType,
163+
DataType = p.DataTypeFull,
164164
IsPrimaryKey = p.IsPrimaryKey
165165
}).ToList();
166166

167-
if (tableMapping.TPHConfiguration != null)
168-
{
169-
properties.Add(new ColumnMapping
170-
{
171-
NameInDatabase = tableMapping.TPHConfiguration.ColumnName,
172-
StaticValue = tableMapping.TPHConfiguration.Mappings[typeof(TEntity)]
173-
});
174-
}
175-
176167
var spec = new UpdateSpecification<TEntity>();
177168
updateSpecification(spec);
178169
provider.UpdateItems(items, tableMapping.Schema, tableMapping.TableName, properties, connectionToUse, batchSize, spec);

EntityFramework.Utilities/EntityFramework.Utilities/MappingHelper.cs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ public class PropertyMapping
9292
public string DataType { get; set; }
9393

9494
public bool IsPrimaryKey { get; set; }
95+
96+
public string DataTypeFull { get; set; }
9597
}
9698

9799
/// <summary>
@@ -172,13 +174,15 @@ public EfMapping(DbContext db)
172174
{
173175
ColumnName = scalar.Column.Name,
174176
DataType = scalar.Column.TypeName,
177+
DataTypeFull = GetFullTypeName(scalar),
175178
PropertyName = path + item.Property.Name,
176179
ForEntityType = t
177180
});
178181
}
179182
};
180183

181-
Func<MappingFragment, Type> getClr = m => {
184+
Func<MappingFragment, Type> getClr = m =>
185+
{
182186
return GetClrTypeFromTypeMapping(metadata, objectItemCollection, m.TypeMapping as EntityTypeMapping);
183187
};
184188

@@ -188,7 +192,7 @@ public EfMapping(DbContext db)
188192
tableMapping.TPHConfiguration = new TPHConfiguration
189193
{
190194
ColumnName = withConditions.First().Fragments[0].Conditions[0].Column.Name,
191-
Mappings = new Dictionary<Type,string>()
195+
Mappings = new Dictionary<Type, string>()
192196
};
193197
foreach (var item in withConditions)
194198
{
@@ -221,6 +225,21 @@ public EfMapping(DbContext db)
221225
}
222226
}
223227

228+
private string GetFullTypeName(ScalarPropertyMapping scalar)
229+
{
230+
if (scalar.Column.TypeName == "nvarchar" || scalar.Column.TypeName == "varchar")
231+
{
232+
return string.Format("{0}({1})", scalar.Column.TypeName, scalar.Column.MaxLength);
233+
}
234+
235+
if (scalar.Column.TypeName == "decimal" || scalar.Column.TypeName == "numeric")
236+
{
237+
return string.Format("{0}({1},{2})", scalar.Column.TypeName, scalar.Column.Precision, scalar.Column.Scale);
238+
}
239+
240+
return scalar.Column.TypeName;
241+
}
242+
224243
private Type GetClrTypeFromTypeMapping(MetadataWorkspace metadata, ObjectItemCollection objectItemCollection, EntityTypeMapping mapping)
225244
{
226245
return GetClrType(metadata, objectItemCollection, mapping.EntityType ?? mapping.IsOfEntityTypes.First());

EntityFramework.Utilities/EntityFramework.Utilities/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.0.0")]
36-
[assembly: AssemblyFileVersion("1.0.0.0")]
35+
[assembly: AssemblyVersion("1.0.1.0")]
36+
[assembly: AssemblyFileVersion("1.0.1.0")]

EntityFramework.Utilities/EntityFramework.Utilities/SqlQueryProvider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void UpdateItems<T>(IEnumerable<T> items, string schema, string tableName
9999

100100
var setters = string.Join(",", filtered.Where(c => !c.IsPrimaryKey).Select(c => "[" + c.NameInDatabase + "] = TEMP.[" + c.NameInDatabase + "]"));
101101
var pks = properties.Where(p => p.IsPrimaryKey).Select(x => "ORIG.[" + x.NameInDatabase + "] = TEMP.[" + x.NameInDatabase + "]");
102-
var filter = string.Join(",", pks);
102+
var filter = string.Join(" and ", pks);
103103
var mergeCommand = string.Format(@"UPDATE [{0}]
104104
SET
105105
{3}

EntityFramework.Utilities/Tests/FakeDomain/Context.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Linq;
66
using System.Text;
77
using Tests.FakeDomain.Models;
8+
using Tests.Models;
89

910
namespace Tests.FakeDomain
1011
{
@@ -22,6 +23,8 @@ private Context(string connectionString)
2223
public DbSet<PhoneNumber> PhoneNumbers { get; set; }
2324
public DbSet<Email> Emails { get; set; }
2425
public DbSet<Comment> Comments { get; set; }
26+
public DbSet<NumericTestObject> NumericTestsObjects { get; set; }
27+
public DbSet<MultiPKObject> MultiPKObjects { get; set; }
2528

2629
protected override void OnModelCreating(DbModelBuilder modelBuilder)
2730
{
@@ -33,6 +36,14 @@ protected override void OnModelCreating(DbModelBuilder modelBuilder)
3336
modelBuilder.Entity<Person>()
3437
.Map<Person>(m => m.Requires("Type").HasValue("Person"))
3538
.Map<Contact>(m => m.Requires("Type").HasValue("Contact"));
39+
40+
modelBuilder.Entity<MultiPKObject>().HasKey(x => new { x.PK1, x.PK2 });
41+
42+
43+
modelBuilder.Entity<BlogPost>().Property(x => x.ShortTitle).HasMaxLength(100);
44+
45+
var n = modelBuilder.Entity<NumericTestObject>();
46+
n.Property(x => x.NumericType).HasColumnType("numeric");
3647
}
3748

3849
public static Context Sql()

EntityFramework.Utilities/Tests/Models/BlogPost.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class BlogPost
99
{
1010
public int ID { get; set; }
1111
public string Title { get; set; }
12+
public string ShortTitle { get; set; }
1213
public DateTime Created { get; set; }
1314
public int Reads { get; set; }
1415
public AuthorInfo Author { get; set; }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Tests.Models
7+
{
8+
public class MultiPKObject
9+
{
10+
public Guid PK1 { get; set; }
11+
public int PK2 { get; set; }
12+
public string Text { get; set; }
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace Tests.Models
7+
{
8+
public class NumericTestObject
9+
{
10+
public int Id { get; set; }
11+
public decimal DecimalType { get; set; }
12+
public decimal NumericType { get; set; }
13+
public float FloatType { get; set; }
14+
}
15+
}

EntityFramework.Utilities/Tests/Models/ReorderedBlogPost.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace Tests.FakeDomain.Models
88
public class ReorderedBlogPost
99
{
1010
public int ID { get; set; }
11+
public string ShortTitle { get; set; }
1112
public DateTime Created { get; set; }
1213
public string Title { get; set; } //<--- Reversed order of this and created for Batch Insert testing
1314
public int Reads { get; set; }

EntityFramework.Utilities/Tests/Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@
7676
<Compile Include="ConnectionStringReader.cs" />
7777
<Compile Include="ConnectionStrings.cs" />
7878
<Compile Include="AttachAndModifyTest.cs" />
79+
<Compile Include="Models\MultiPKObject.cs" />
80+
<Compile Include="Models\NumericTestObject.cs" />
7981
<Compile Include="UpdateBulkTests.cs" />
8082
<Compile Include="FakeDomain\Contact.cs" />
8183
<Compile Include="FakeDomain\Email.cs" />

EntityFramework.Utilities/Tests/UpdateBulkTests.cs

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
using Microsoft.VisualStudio.TestTools.UnitTesting;
55
using Tests.FakeDomain;
66
using Tests.FakeDomain.Models;
7+
using Tests.Models;
8+
using System;
79

810
namespace Tests
911
{
@@ -34,6 +36,147 @@ public void UpdateBulk_UpdatesAll()
3436
}
3537
}
3638

39+
[TestMethod]
40+
public void UpdateBulk_CanUpdateTPH()
41+
{
42+
using (var db = Context.Sql())
43+
{
44+
if (db.Database.Exists())
45+
{
46+
db.Database.Delete();
47+
}
48+
db.Database.Create();
49+
50+
List<Contact> people = new List<Contact>();
51+
people.Add(Contact.Build("FN1", "LN1", "Director"));
52+
people.Add(Contact.Build("FN2", "LN2", "Associate"));
53+
people.Add(Contact.Build("FN3", "LN3", "Vice President"));
54+
55+
EFBatchOperation.For(db, db.People).InsertAll(people);
56+
}
57+
58+
using (var db = Context.Sql())
59+
{
60+
var contacts = db.Contacts.ToList();
61+
62+
foreach (var contact in contacts)
63+
{
64+
contact.FirstName = contact.Title + " " + contact.FirstName;
65+
}
66+
67+
EFBatchOperation.For(db, db.People).UpdateAll(contacts, x => x.ColumnsToUpdate(p => p.FirstName));
68+
}
69+
70+
using (var db = Context.Sql())
71+
{
72+
var contacts = db.People.OfType<Contact>().OrderBy(c => c.LastName).ToList();
73+
Assert.AreEqual(3, contacts.Count);
74+
Assert.AreEqual("Director FN1", contacts.First().FirstName);
75+
}
76+
}
77+
78+
[TestMethod]
79+
public void UpdateBulk_CanUpdateNumerics()
80+
{
81+
using (var db = Context.Sql())
82+
{
83+
if (db.Database.Exists())
84+
{
85+
db.Database.ForceDelete();
86+
}
87+
db.Database.Create();
88+
89+
var list = new List<NumericTestObject>(){
90+
new NumericTestObject{ }
91+
};
92+
93+
EFBatchOperation.For(db, db.NumericTestsObjects).InsertAll(list);
94+
}
95+
96+
using (var db = Context.Sql())
97+
{
98+
var items = db.NumericTestsObjects.ToList();
99+
foreach (var item in items)
100+
{
101+
item.DecimalType = 1.1m;
102+
item.FloatType = 2.1f;
103+
item.NumericType = 3.1m;
104+
}
105+
EFBatchOperation.For(db, db.NumericTestsObjects).UpdateAll(items, spec => spec.ColumnsToUpdate(p => p.DecimalType, p => p.FloatType, p => p.NumericType));
106+
}
107+
108+
using (var db = Context.Sql())
109+
{
110+
var item = db.NumericTestsObjects.First();
111+
Assert.AreEqual(1.1m, item.DecimalType);
112+
Assert.AreEqual(2.1f, item.FloatType);
113+
Assert.AreEqual(3.1m, item.NumericType);
114+
}
115+
}
116+
117+
[TestMethod]
118+
public void UpdateBulk_CanUpdateMultiPK()
119+
{
120+
using (var db = Context.Sql())
121+
{
122+
if (db.Database.Exists())
123+
{
124+
db.Database.ForceDelete();
125+
}
126+
db.Database.Create();
127+
128+
var guid = Guid.NewGuid();
129+
var list = new List<MultiPKObject>(){
130+
new MultiPKObject{ PK1 = guid, PK2 = 0 },
131+
new MultiPKObject{ PK1 = guid, PK2 = 1 }
132+
};
133+
134+
EFBatchOperation.For(db, db.MultiPKObjects).InsertAll(list);
135+
}
136+
137+
using (var db = Context.Sql())
138+
{
139+
var items = db.MultiPKObjects.ToList();
140+
var index = 1;
141+
foreach (var item in items)
142+
{
143+
item.Text = "#" + index++;
144+
}
145+
EFBatchOperation.For(db, db.MultiPKObjects).UpdateAll(items, spec => spec.ColumnsToUpdate(p => p.Text));
146+
}
147+
148+
using (var db = Context.Sql())
149+
{
150+
var items = db.MultiPKObjects.OrderBy(x => x.PK2).ToList();
151+
Assert.AreEqual("#1", items[0].Text);
152+
Assert.AreEqual("#2", items[1].Text);
153+
}
154+
}
155+
156+
[TestMethod]
157+
public void UpdateBulk_CanUpdateNvarcharWithLength()
158+
{
159+
Setup();
160+
161+
using (var db = Context.Sql())
162+
{
163+
var posts = db.BlogPosts.ToList();
164+
foreach (var post in posts)
165+
{
166+
post.ShortTitle = post.Title.Replace("1", "4").Replace("2", "8").Replace("3", "12");
167+
}
168+
EFBatchOperation.For(db, db.BlogPosts).UpdateAll(posts, spec => spec.ColumnsToUpdate(p => p.ShortTitle));
169+
}
170+
171+
using (var db = Context.Sql())
172+
{
173+
var posts = db.BlogPosts.OrderBy(b => b.ID).ToList();
174+
Assert.AreEqual("T4", posts[0].ShortTitle);
175+
Assert.AreEqual("T8", posts[1].ShortTitle);
176+
Assert.AreEqual("T12", posts[2].ShortTitle);
177+
}
178+
}
179+
37180
private static void Setup()
38181
{
39182
using (var db = Context.Sql())

0 commit comments

Comments
 (0)