How can I display certain rows of a data table? - database

When displaying my CollectionView (which contains the data), I would like to display only the rows that have the field "Number" = xx
Currently I display my data like this:
public async Task<List<DB_PosteNF>> ListerPF()
{
try
{
return await connection.Table<DB_PosteNF>().ToListAsync();
}
catch (Exception ex)
{
StatutMessage = $"Impossible d'afficher la liste des postes de frais. \nErreur : {ex.Message}";
}
return new List<DB_PosteNF>();
}
Here is the structure of my tables, I would like Primary Key number = Foreign Key
Table 1:
Primary Key = Number
Table 2:
Primary Key = Id
Foreign key = Number

Use LINQ
connection.Table<DB_PosteNF>().Where(x => x.Number == SomeValue).ToListAsync();
Replace SomeValue with value you want to filter by

Related

Problem when inserting two consecutive lines to the database

I have this function and it is working perfectly
public DemandeConge Creat(DemandeConge DemandeConge)
{
try
{
var _db = Context;
int numero = 0;
//??CompanyStatique
var session = _httpContextAccessor.HttpContext.User.Claims.ToList();
int currentCompanyId = int.Parse(session[2].Value);
numero = _db.DemandeConge.AsEnumerable()
.Where(t => t.companyID == currentCompanyId)
.Select(p => Convert.ToInt32(p.NumeroDemande))
.DefaultIfEmpty(0)
.Max();
numero++;
DemandeConge.NumeroDemande = numero.ToString();
//_db.Entry(DemandeConge).State = EntityState.Added;
_db.DemandeConge.Add(DemandeConge);
_db.SaveChanges();
return DemandeConge;
}
catch (Exception e)
{
return null;
}
}
But just when i try to insert another leave demand directly after inserting one (without waiting or refreshing the page )
An error appears saying that this new demand.id exists
I think that i need to add refresh after saving changes?
Any help and thanks
Code like this:
numero = _db.DemandeConge.AsEnumerable()
.Where(t => t.companyID == currentCompanyId)
.Select(p => Convert.ToInt32(p.NumeroDemande))
.DefaultIfEmpty(0)
.Max();
numero++;
Is a very poor pattern. You should leave the generation of your "numero" (ID) up to the database via an Identity column. Set this up in your DB (if DB First) and set up your mapping for this column as DatabaseGenerated.Identity.
However, your code raises lots of questions.. Why is it a String instead of an Int? This will be a bugbear for using an identity column.
The reason you will want to avoid code like this is because each request will want to query the database to get the "max" ID, as soon as you get two requests running relatively simultaneously you will get 2 requests that say the max ID is "100" before either can reserve and insert 101, so both try to insert 101. By using Identity columns the database will get 2x inserts and give them an ID first-come-first-serve. EF can manage associating FKs around these new IDs automatically for you when you set up navigation properties for the relations. (Rather than trying to set FKs manually which is the typical culprit for developers trying to fetch a new ID app-side)
If you're stuck using an existing schema where the PK is a combination of company ID and this Numero column as a string then about all you can do is implement a retry strategy to account for duplicates:
const int MAXRETRIES = 5;
var session = _httpContextAccessor.HttpContext.User.Claims.ToList();
int currentCompanyId = int.Parse(session[2].Value);
int insertAttemptCount = 0;
while(insertAttempt < MAXRETRIES)
{
try
{
numero = Context.DemandeConge
.Where(t => t.companyID == currentCompanyId)
.Select(p => Convert.ToInt32(p.NumeroDemande))
.DefaultIfEmpty(0)
.Max() + 1;
DemandeConge.NumeroDemande = numero.ToString();
Context.DemandeConge.Add(DemandeConge);
Context.SaveChanges();
break;
}
catch (UpdateException)
{
insertAttemptCount++;
if (insertAttemptCount >= MAXRETRIES)
throw; // Could not insert, throw and handle exception rather than return #null.
}
}
return DemandeConge;
Even this won't be fool proof and can result in failures under load, plus it is a lot of code to work around a poor DB design so my first recommendation would be to fix the schema because coding like this is prone to errors and brittle.

How to get primary key name on laravel query builder

Is there a way to get a table's primary key name using the Laravel query builder? Can i do something like
$key = DB::table($someTable)->getPrimaryKey();
I've looked through the documentation and API but couldn't find any reference to it.
Thanks in advance.
You can get an array of indexes for a table directly using the Schema manager:
$indexes = DB::connection()->getDoctrineSchemaManager()->listTableIndexes($table);
OR
$indexes = Schema::getConnection()->getDoctrineSchemaManager()->listTableIndexes($table);
And then you can get an array of the columns associated with that index key:
$columns = $indexes[ 'primary' ]->getColumns();
This function can be used to find the primary key(s) or unique key(s) for a table you know nothing about:
public function getTablePrimaryOrUniqueKey($table, $key='') {
//get the array of table indexes
$indexes = DB::connection()->getDoctrineSchemaManager()->listTableIndexes($table);
//abort if there are no indexes
if(!is_array($indexes)) return false;
//set up the default array of index keys
$keys = ['primary', 'unique'];
//if a key was passed and it is valid, use it...but cast as an array
if($key!='' && in_array($key, $keys)) $keys = (array) $key;
//loop through the keys array
foreach ( $keys as $key ) {
//keep it honest
if ( array_key_exists( $key, $indexes ) ) {
//get the columns for this key
$columns = $indexes[ $key ]->getColumns();
//if we have an array of columns, we have what we need
if ( is_array( $columns ) ) {
return $columns;
}
}
}
//if you got here, you did not get find what you were looking for
return false;
}
The Illuminate/Database/Eloquent/Model class has a getKeyName function which is public.
Inside your model class, you can access the primary key using $this->getKeyName().
my approach is :
$result = DB::select(DB::raw("SHOW KEYS FROM {$table} WHERE Key_name = 'PRIMARY'"));
$primaryKey = $result[0]->Column_name;
and i use mysql
You can use ->getKey() on a model:
$someModel->getKey();
Or if you're just trying to get the name of the column, without having an instance of the model:
app(App\Model::class)->getKeyName()
$primary_key = app($builder->getModel())->getKeyName();
if you referenced the model when you initialized that Query Builder instance you can retrieve the model reference then use it to get the keyName. but if your just directly called a new Query Builder there isn't a way to see the primary key without doing a select against the table keys, maybe in a subselect?
SHOW KEYS FROM table WHERE Key_name = 'PRIMARY'

Yii2 return single value of attribute on condition

I have these tables in the database:
user : userid (primary Key), professionid, etc,
profession : professionid (primary Key), classid, etc,
class : classid (primary key), etc,
In model of User, I create function,
public function getClassid()
{
return 1;
}
How can I replace 1 to value of classid in table of profession, where userid is current logged user?
Use
return model->profession->classid
This should work
public function getClassid()
{
$profession = Profession::findOne(['professionid' = > $this->profession_id])
return $profession->classid;
}
This returns the value of the attribute classid which is stored in the table Profession where the professionid is the same and the professionid of the current User model.
Hope this helps

One to Many relationship using breezejs

I have the following one to many relationship setup between two tables (Case and Recipient)
Case table has one primary key which is identified as an identity (auto-increment) tblRecipient has one primary key which is identified as an identity (auto-increment),and a foreign key relationship with Case.
Case table and related tblRecipient data is pulled:
function searchCases(caseID, caseNum)
{
var qPredicate;
if (caseID != '')
{
qPredicate = new breeze.Predicate("pkCaseID", "==", parseInt(caseID));
}
else if (caseNum != null)
{
qPredicate = new breeze.Predicate("CaseNumber", "Contains", caseNum);
}
var query = breeze.EntityQuery
.from("case")
.where(qPredicate)
.expand("tblRecipients")
return manager.executeQuery(query);
}
When a button is pressed to add a new recipient, the following code is used to create a new recipient entity:
function createNewRecipient(CaseID)
{
var recipientEntityType = manager.metadataStore.getEntityType("tblRecipient");
var newRecipient = manager.createEntity(recipientEntityType, {fkCaseID: CaseID});
return newRecipient;
}
This code returns this error:
Error: Cannot attach an object to an EntityManager without first setting its key or setting its entityType 'AutoGeneratedKeyType' property to something other than 'None'
The AutoGeneratedKeyType in the metadata shows None instead of Identity as in the Case table. We are not sure what we need to change or how to really debug this. Any help would be appreciated.

MVC: The INSERT statement conflicted with the FOREIGN KEY constraint

I have two tables that are supposed to be related.
Tables and Coloums Specification
Primary key table
ProductCategory
ProductCategoryID
Foreign key table
SubProductCategory2
ProductCategoryID
In the controller I have the following methods when creating sub category...
public ActionResult Create()
{
ViewBag.ProductCategory = db.ProductCategories.OrderBy(p =>
p.ProductCategoryID).ToList();
ViewBag.SubProductCategory2 = db.SubProductCategory2.OrderBy(a =>
a.ProductCategoryID).ToList();
var PC2 = new SubProductCategory2();
return View(PC2);
}
public ActionResult Create(SubProductCategory2 Createsubcat2,
FormCollection values)
{
if (ModelState.IsValid)
{
db.AddToSubProductCategory2(Createsubcat2);
db.SaveChanges();
//error pointing here and the full error message I am getting is...
/*error: System.Data.SqlClient.SqlException:
* The INSERT statement conflicted with the FOREIGN KEY constraint
* "FK_SubProductCategory2_ProductCategory". The conflict occurred in
* database "MyHouseDB", table "dbo.ProductCategory", column
* 'ProductCategoryID'. The statement has been terminated.*/
return RedirectToAction("/");
}
ViewBag.ProductCategory = db.ProductCategories.OrderBy(p =>
p.ProductCategoryID).ToList();
ViewBag.SubProductCategory2 = db.SubProductCategory2.OrderBy(a =>
a.ProductCategoryID).ToList();
return View(Createsubcat2);
}
ViewBag.ProductCategory = db.ProductCategories.OrderBy(p =>
p.ProductCategoryID).ToList();
ViewBag.SubProductCategory2 = db.SubProductCategory2.OrderBy(a =>
a.ProductCategoryID).ToList();
return View(Createsubcat2);
in the views I have the following code...
<div class="editor-label">
#Html.LabelForModel()
</div>
<div class="editor-field">
#Html.DropDownList("CategoryName", new
SelectList((System.Collections.IEnumerable)ViewData["ProductCategory"],
"ProductCategoryID", "CategoryName"))
#Html.ValidationMessageFor(model => model.ProductCategory.CategoryName)
Could some tell me how to solve the The INSERT statement conflicted with the FOREIGN KEY constraint error message. Correct me if I'm wrong, have I created the relationship between two tables incorrectly or the problem else where? Thanks in advance.
This error happens when the following conditions are true 1) The value that you selected for "ProductCategoryID" is not present in the "ProductCategory" table OR 2) The product category table is empty.
Does you have values in the product category table?
What value are you choosing for ProductCategoryID?
I have found the problem. It was my sql database design not MVC coding side. I removed CategoryName column from SubCategory table. I could have felt the CategoryName as long as Allow Null was set to true. There was no point in doing that has PrimaryKey had been setup correctly for the two tables.

Resources