EF Fluent API - HasIndex for complex field - entity-framework

I need to use Fluent API (no DataAnnotation) and should create complex Index (3 fields). I try to do it:
this.HasIndex(p => p.LoadId).HasName("IX_UniqueLoad").IsUnique();
this.HasIndex(p => p.LocationId).HasName("IX_UniqueLoad").IsUnique();
this.HasIndex(p => p.StopAction).HasName("IX_UniqueLoad").IsUnique();
but it says:
The index with name 'IX_UniqueLoad' on table 'dbo.Stop' has the same
column order of '-1' specified for columns 'LoadId' and 'LocationId'.
Make sure a different order value is used for the IndexAttribute on
each column of a multi-column index.
How to do it?

I found solution:
this.HasIndex(p => new { p.LoadId, p.LocationId, p.StopAction }).IsUnique();
it will generates:
CreateIndex("dbo.Stop", new[] { "LoadId", "LocationId", "StopAction" }, unique: true);

Related

EF Core - projections as string

I would like to create an API which lets query all fields and relations' fields (transitively) of an entity.
Let's see through an example, using from EF-demo Students-Courses-Ennrollment data model: https://learn.microsoft.com/en-us/aspnet/core/data/ef-rp/intro
The following HTTP request would request 3 fields (I hope the syntax is understandable):
GET /students?$select=FirstName,Ennrollments(12345).Grade,Ennrollments(67890).Course.Title
Then the corresponding query would be something like:
context.Students.Select(s => new
{
s.FirstName,
s.Ennrollments.First(e => e.EnnrollmentId == 12345).Grade,
s.Ennrollments.First(e => e.EnnrollmentId == 67890).Course.Title
});
So I'd dynamically map string field "references" to projections/EF expressions. Is this something possible to achieve with EF Core? For example using Metadata?

Compound fields in search

I'm trying to get first name and last name from a related table
I've tried using an accessor on the related table which works fine when loading the page and for adding/editing but when searching it shows an error
Column not found: 1054 Unknown column 'FullName' in 'where clause'
This column obviously does not exist.
So I have this in my related model
{
return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
}
And under the Backpack crud Controller I have
$this->crud->addColumn([ // n-n relationship (with pivot table)
'label' => 'Account', // Table column heading
'type' => 'select',
'name' => 'user_id', // the method that defines the relationship in your Model
'entity' => 'user', // the method that defines the relationship in your Model
'attribute' => 'FullName', // foreign key attribute that is shown to user
'model' => "App\Models\BackpackUser", // foreign key model
]);
Where am I making a mistake, input would be very much appreciated.
That needs a real column.
You can use a view (like you already do) or a model_function column to format the table cell value in your model class - https://backpackforlaravel.com/docs/3.5/crud-columns#model_function
Just see what's simpler for you.
Note: if ordering or searching doesn't work as expected see https://backpackforlaravel.com/docs/3.5/crud-columns#custom-search-logic-for-columns and https://backpackforlaravel.com/docs/3.5/crud-columns#custom-order-logic-for-columns

Ordering query using lambda expression and Include method

I am working on a Entity-Framework-Core 2.0 query. The query needs to sort 2 tables by the "order" field. So far that's what I have:
return await _context.FieldsetGroup
.Include(e => e.Fieldsets.OrderBy(o => o.Order))
.ThenInclude(e => e.FieldsetFields.OrderBy(o => o.Field.Order))
.ThenInclude(e => e.Field)
.FirstOrDefaultAsync(fsg => fsg.FieldsetGroupId == fieldSetGroupId);
This query returns an exception:
"The property expression 'e => {from Fieldset o in e.Fieldsets orderby [o].Order asc select [o]}' is not valid. The expression should represent a property access: 't => t.MyProperty'. For more information on including related data, see http://go.microsoft.com/fwlink/?LinkID=746393."
How can I sort the 2 tables?
One of the slower parts of database queries is the transport of your selected data from the DBMS to your local process. Hence it is wise to limit the amount of transferred data.
Apparently your FieldSetGroup has zero or more FieldSets. Each FieldSet belongs to exactly one FieldsetGroup. This is identified by the foreign key FieldSetGroupId. The value of this field equals the Id of the FieldSetGroup.
So if you have FieldSetGroupwith Id = 10, and this FieldSetGroup has, 1000 FieldSets, then every FieldSet will have a value of foreign key FieldSetGroupId of 10. No need to transfer this value 1000 times.
Advice: To limit the amount of transferred data, avoid transferring more data than needed, use Select instead of Include and select only the data you actually plan to
use. Use Include if you plan to update the fetched data.
If you use Select, you can order whatever you want:
var result = dbContext.FieldsetGroup
.Where((fieldSetGroup => fieldSetGroup.FieldsetGroupId == fieldSetGroupId)
.Select(fieldSetGroup => new
{
... // select the fieldSetGroup properties you plan to use
FieldSets = fieldSetGroup.FieldSets
.OrderBy(fieldSet => fieldSet.Order)
.Select(fieldSet => new
{
... // only select the fieldSet properties you plan to use
FieldSetFields = fieldSet.FieldSetFields
.OrderBy(fieldSetField => fieldSetField.Order)
.Select(fieldSetField => new
{
...
})
.ToList(),
})
.ToList(),
})
.ToList(),
})
.FirstOrDefault();
You cannot do sorting (OrderBy) inside the Include method. Sort the data after the query.

add column to select object zend framework

Here is my current code:
$Select=new Select();
$Select->from($this->getTable());
What I want now is to add the id column but as DT_RowId instead of id. How do I accomplish this? The goal would be to have all of the table columns as well as this new column.
If you need both "old" and "new" fields, don't forget to add an asterisk.
$Select=new \Zend\Db\Sql\Select();
$Select->from($this->getTable());
$Select->columns([
'*',
'DT_RowId' => 'id',
'furtherColumn' => 'furtherColumn'
]);
The simplest soloution would be to use the columns function with an associative array with aliases as the keys for example:
$select=new Select();
$select->from($this->getTable());
$select->columns(array(
'DT_RowId' => 'id',
'furtherColumn' => 'furtherColumn',
));

how can create Unique Constraint with multi column with entityframework

I'm use Entityframework Code First, and an EntityTypeConfiguration using fluent API.
how can create Unique Constraint with multi column.
for example i have a table with below field
Id
CompanyId
Code
Name
i want set Code column to unique , per CompanyId
In your EntityTypeConfiguration you can do something like this:
Property(m => m.CompanyId)
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_YourUniqueIndexName", 1) { IsUnique = true }));
Property(m => m.Code)
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_YourUniqueIndexName", 2) { IsUnique = true }));
This will create a unique index on those 2 columns.
Make sure you use the same name for the unique index. Both need to be name "IX_YourUniqueIndex". If one is called "IX_Index1" and the other "IX_Index2" then it will create a unique index on each, which is not what you want