Skip to content

Commit d58f119

Browse files
committed
Support for selectable SPs.
1 parent a8be051 commit d58f119

File tree

2 files changed

+85
-3
lines changed

2 files changed

+85
-3
lines changed

Provider/src/FirebirdSql.EntityFrameworkCore.Firebird.Tests/Query/ElementaryTests.cs

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,45 @@ public async Task SelectSkip()
132132
[Test]
133133
public async Task SelectTopLevelAny()
134134
{
135-
if (!await EnsureVersion(new Version(3, 0, 0, 0)))
136-
return;
137-
138135
await using (var db = await GetDbContext<SelectContext>())
139136
{
140137
Assert.DoesNotThrowAsync(() => db.Set<MonAttachment>().AnyAsync(x => x.AttachmentId != 0));
141138
}
142139
}
140+
141+
[Test]
142+
public async Task SelectableProcedureSimple()
143+
{
144+
await using (var db = await GetDbContext<SelectContext>())
145+
{
146+
db.CreateProcedures();
147+
var query = db.Set<SelectableProcedure>();
148+
Assert.DoesNotThrowAsync(() => query.LoadAsync());
149+
}
150+
}
151+
152+
[Test]
153+
public async Task SelectableProcedureWithTable()
154+
{
155+
await using (var db = await GetDbContext<SelectContext>())
156+
{
157+
db.CreateProcedures();
158+
var query = db.Set<MonAttachment>()
159+
.Where(x => db.Set<SelectableProcedure>().Select(y => y.Value).Contains(x.AttachmentId));
160+
Assert.DoesNotThrowAsync(() => query.LoadAsync());
161+
}
162+
}
163+
164+
[Test]
165+
public async Task SelectableProcedureWithParam()
166+
{
167+
await using (var db = await GetDbContext<SelectContext>())
168+
{
169+
db.CreateProcedures();
170+
var query = db.SelectableProcedureWithParam(10).Where(x => x.Value > 10);
171+
Assert.DoesNotThrowAsync(() => query.LoadAsync());
172+
}
173+
}
143174
}
144175

145176
class SelectContext : FbTestDbContext
@@ -203,6 +234,18 @@ protected override void OnTestModelCreating(ModelBuilder modelBuilder)
203234
monAttachmentConf.Property(x => x.AttachmentName).HasColumnName("MON$ATTACHMENT_NAME");
204235
monAttachmentConf.Property(x => x.Timestamp).HasColumnName("MON$TIMESTAMP");
205236
monAttachmentConf.ToTable("MON$ATTACHMENTS");
237+
238+
var selectableProcedureConf = modelBuilder.Entity<SelectableProcedure>();
239+
selectableProcedureConf.HasNoKey();
240+
selectableProcedureConf.Property(x => x.Value).HasColumnName("VAL");
241+
selectableProcedureConf.ToFunction("SELECTABLE_PROCEDURE");
242+
243+
var selectableProcedureWithParamConf = modelBuilder.Entity<SelectableProcedureWithParam>();
244+
selectableProcedureWithParamConf.HasNoKey();
245+
selectableProcedureWithParamConf.Property(x => x.Value).HasColumnName("VAL");
246+
modelBuilder.HasDbFunction(typeof(SelectContext).GetMethod(nameof(SelectableProcedureWithParam)),
247+
c => c.HasName("SELECTABLE_PROCEDURE"));
248+
206249
}
207250

208251
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
@@ -214,6 +257,22 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
214257
}
215258

216259
public string LastCommandText => _lastCommandTextInterceptor.LastCommandText;
260+
261+
public IQueryable<SelectableProcedureWithParam> SelectableProcedureWithParam(int i) => FromExpression(() => SelectableProcedureWithParam(i));
262+
263+
public void CreateProcedures()
264+
{
265+
Database.ExecuteSqlRaw(
266+
@"recreate procedure selectable_procedure (i int = 6)
267+
returns (val int)
268+
as
269+
begin
270+
val = i;
271+
suspend;
272+
val = i + 1;
273+
suspend;
274+
end");
275+
}
217276
}
218277

219278
class MonAttachment
@@ -222,4 +281,13 @@ class MonAttachment
222281
public string AttachmentName { get; set; }
223282
public DateTime Timestamp { get; set; }
224283
}
284+
285+
class SelectableProcedure
286+
{
287+
public int Value { get; set; }
288+
}
289+
class SelectableProcedureWithParam
290+
{
291+
public int Value { get; set; }
292+
}
225293
}

Provider/src/FirebirdSql.EntityFrameworkCore.Firebird/Query/Internal/FbQuerySqlGenerator.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,20 @@ protected override Expression VisitOrdering(OrderingExpression orderingExpressio
244244
return orderingExpression;
245245
}
246246

247+
protected override Expression VisitTableValuedFunction(TableValuedFunctionExpression tableValuedFunctionExpression)
248+
{
249+
Sql.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(tableValuedFunctionExpression.StoreFunction.Name));
250+
if (tableValuedFunctionExpression.Arguments.Any())
251+
{
252+
Sql.Append("(");
253+
GenerateList(tableValuedFunctionExpression.Arguments, e => Visit(e));
254+
Sql.Append(")");
255+
}
256+
Sql.Append(AliasSeparator);
257+
Sql.Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(tableValuedFunctionExpression.Alias));
258+
return tableValuedFunctionExpression;
259+
}
260+
247261
public virtual Expression VisitSubstring(FbSubstringExpression substringExpression)
248262
{
249263
Sql.Append("SUBSTRING(");

0 commit comments

Comments
 (0)