I have a client-server app using Janus GridEx and Linq2Sql.
I have a grid that has one sub-table; Invoices (root) and Invoice Items (sub).
I would like to only retrieve invoice items when the invoice row is expanded..
Is this possible?
I think Yes , I have done this with EntityFramework (WinForm) , it should works for LinqToSql
First you need to Add a property to your Invoice class, use "partial" to do this
partial class Invoice
{
public List<InvoiceItem> InvoiceItemList { get { return this.InvoiceItems.ToList();} }
}
then add a Child table for this property to your gridex.
if you have lazy loading and proxy 'ON' and did not dispose your context,you must have not any other problem
Related
I'm very much a beginner when it comes to database relationships hence what I suspect is a basic question! I have two database tables as follows:
Projects
id
company_id
name
etc...
rfis
id
project_id (foreign key is id on the Projects table above)
Number (this is the column I need help with - more below)
question
The relationships at the Model level for these tables are as follows:
Project
public function rfi()
{
return $this->hasMany('App\Rfi');
}
RFI
public function project()
{
return $this->belongsTo('App\Project');
}
What I'm trying to achieve
In the RFI table I need a system generated number or essentially a count of RFI's. Where I'm finding the difficulty is that I need the RFI number/count to start again for each project. To clarify, please see the RFI table below which I have manually created with the the 'number' how I would like it displayed (notice it resets for each new project and the count starts from there).
Any assistance would be much appreciated!
Todd
So the number field depends on the number of project_id in the RFI table. It is exactly the number of rows with project_id plus one.
So when you want to insert a new row, you calculate number based on project_id and assign it.
RFI::create([
'project_id' => $project_id,
'number' => RFI::where('project_id', $project_id)->count() + 1,
...
]);
What I understood is that you want to set the value of the "number" field to "1" if it's a new project and "increment" if it's an existing project. And you want to automate this without checking for it every time you save a new row for "RFI" table.
What you need is a mutator. It's basically a method that you will write inside the desired Model class and there you will write your own logic for saving data. Laravel will run that function automatically every time you save something. Here you will learn more about mutators.
Use this method inside the "RFI" model class.
public function setNumberAttribute($value)
{
if(this is new project)
$this->attributes['number'] = 1;
else
$this->attributes['number']++;
}
Bonus topic: while talking about mutators, there's also another type of method called accessor. It does the same thing as mutators do, but just the opposite. Mutators get called while saving data, accessors get called while fetching data.
I have two columns quantity and remaining_quantity in my stock table. I wanted to copy same data from quantity to remaining_quantity while doing a create function. Is there any function in Laravel for that?
You can do that by creating an observer.
1- Create a folder called observers in you app folder.
2- Create a file named MyModelObserver.php for example StockObserver.php.
3- Prepare your class like the following:
<?php
namespace App\Observers;
class StockObserver
{
//
}
Inside that class you can create creating, created, updated, updated, deleting, deleted, saving and saved methods. Which their jobs are obvious from their names.
For more details see => https://laravel.com/docs/5.5/eloquent#events
For example the following code will do something everytime an object of Stock model is created.
<?php
namespace App\Observers;
use App\Stock;
class StockObserver
{
public function created(Stock $stock)
{
$stock->remaining_quantity = $stock->quantity;
$stock->save()
}
}
But all these code won't be effective unless you observe that in the AppServiceProvide .. so in the boot method in AppServiceProvider write the following.
\App\Stock::observe(\App\Observers\StockObserver::class);
That's it .. Hope it helps.
Yes, a few different ways to do that. An easy, dirty way would be to just have two queries,
$quantity = StockTable::find($id);
StockTable::create([
'remaining_quantity' => $quantity->quantity
]);
So you grab the record you want to copy a bit of, and then set it as the remaining quantity on your creating record.
I've done some searches (over the web and SO) but so far have been unable to find something that directly answer this:
Is there anyway to force L2S to use a Stored Procedure when acessing a Database?
This is different from simply using SPROC's with L2S: The thing is, I'm relying on LINQ to lazy load elements by accessing then through the generated "Child Property". If I use a SPROC to retrieve the elements of one table, map then to an entity in LINQ, and then access a child property, I believe that LINQ will retrieve the register from the DB using dynamic sql, which goes against my purpose.
UPDATE:
Sorry if the text above isn't clear. What I really want is something that is like the "Default Methods" for Update, Insert and Delete, however, to Select. I want every access to be done through a SPROC, but I want to use Child Property.
Just so you don't think I'm crazy, the thing is that my DAL is build using child properties and I was accessing the database through L2S using dynamic SQL, but last week the client has told me that all database access must be done through SPROCS.
i don't believe that there is a switch or setting that out of the box and automagically would map to using t sprocs the way you are describing. But there is now reason why you couldn't alter the generated DBML file to do what you want. If I had two related tables, a Catalog table and CatalogItem tables, the Linq2SQL generator will naturally give me a property of CatalogItems on Catalog, code like:
private EntitySet<shelf_myndr_Previews_CatalogItem> _shelf_myndr_Previews_CatalogItems;
[global::System.Data.Linq.Mapping.AssociationAttribute(Name="CatalogItem", Storage="_CatalogItems", ThisKey="Id", OtherKey="CatalogId")]
public EntitySet<CatalogItem> CatalogItems
{
get
{
return this._CatalogItems;
//replace this line with a sproc call that ultimately
//returns the expected type
}
set
{
this._CatalogItems.Assign(value);
//replace this line with a sproc call that ultimately
//does a save operation
}
}
There is nothing stopping you from changing that code to be sproc calls there. It'd be some effort for larger applications and I'd be sure that you be getting the benefit from it that you think you would.
How about loading the child entities using the partial OnLoaded() method in the parent entity? That would allow you to avoid messing with generated code. Of course it would no longer be a lazy load, but it's a simple way to do it.
For example:
public partial class Supplier
{
public List<Product> Products { get; set; }
partial void OnLoaded()
{
// GetProductsBySupplierId is the SP dragged into your dbml designer
Products = dataContext.GetProductsBySupplierId(this.Id).ToList();
}
}
Call your stored procedure this way:
Where GetProductsByCategoryName is the name of your stored procedure.
http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx
I am using VS2010 and C#
When I map/select my database tables with LINQ to SQL I have to option to change the "member" propery, but when i delete the table (because I changed something in the schema for example) and add it again the member value gets "reset". Is it possible to set/override this member programmaticly, so that I dont have to change it by hand everytime
I mean the member option of
'<'Table Name="dbo.table1" Member="table1">
All L2S ORM classes are partial, so you should be able to encapsulate the table in another property by extending the DataContext class e.g.
public partial class MyDataContext
{
public IEnumerable<Entity> Table
{
get { return DatabaseTable; }
}
}
So in the above scenario you would make your DatabaseTable private and expose it through a another property. You may still need to change that particular piece of code manually if you change the name of your table, but it means you are only changing it once and don't have to change it everytime you reference the table somewhere in your code.
I feel like this should be easy, but I don't see any way to do it.
I'm using ASP.NET Dynamic Data with Linq to SQL. I've got a table with an Association to the Technician table. The Parent Property is TechAssignment, and on the web form I'm using a DynamicField to display it.
This works fine really, it correctly sees it as a ForeignKeyField and uses that template to give me a dropdown with a list of techs from the Technicians table.
The only problem is that it gives me a list of ALL the technicians, when there are quite a few who are inactive. How can I tell Dynamic Data to filter out inactive technicians so they can't be selected?
LINQ to SQL generates partial classes.
Add a new property (copy from the other foreign key property)
Apply the filter in the get (either by LINQ2SQL or filtering the original property)
Bind to that property
Example UnapprovedContacts in Association table
public partial class Association
{
public IList<Contact> UnapprovedContacts
{
get
{
return Contacts.Where(c => !c.IsApproved).ToList();
}
}
}