Linq to SQL: DISTINCT with Anonymous Types - linq-to-sql

Given this code:
dgIPs.DataSource =
from act in Master.dc.Activities
where act.Session.UID == Master.u.ID
select new
{
Address = act.Session.IP.Address,
Domain = act.Session.IP.Domain,
FirstAccess = act.Session.IP.FirstAccess,
LastAccess = act.Session.IP.LastAccess,
IsSpider = act.Session.IP.isSpider,
NumberProblems = act.Session.IP.NumProblems,
NumberSessions = act.Session.IP.Sessions.Count()
};
How do I pull the Distinct() based on distinct Address only? That is, if I simply add Distinct(), it evaluates the whole row as being distinct and thusly fails to find any duplicates. I want to return exactly one row for each act.Session.IP object.
I've already found this answer, but it seems to be a different situation. Also, Distinct() works fine if I just select act.Session.IP, but it has a column I wish to avoid retrieving and I'd rather not have to do this by manually binding my datagrid columns.

dgIPs.DataSource =
from act in Master.dc.Activities
where act.Session.UID == Master.u.ID
group act by act.Session.IP.Address into g
let ip = g.First().Session.IP
select new
{
Address = ip.Address,
Domain = ip.Domain,
FirstAccess = ip.FirstAccess,
LastAccess = ip.LastAccess,
IsSpider = ip.isSpider,
NumberProblems = ip.NumProblems,
NumberSessions = ip.Sessions.Count()
};
Or:
dgIPs.DataSource =
from act in Master.dc.Activities
where act.Session.UID == Master.u.ID
group act.Session.IP by act.Session.IP.Address into g
let ip = g.First()
select new
{
Address = ip.Address,
Domain = ip.Domain,
FirstAccess = ip.FirstAccess,
LastAccess = ip.LastAccess,
IsSpider = ip.isSpider,
NumberProblems = ip.NumProblems,
NumberSessions = ip.Sessions.Count()
};

One of the overloads of Enumerable.Distinct accepts an IEqualityComparer instance. Simply write a class that implements IEqualityComparer and which only compares the two Address properties.
Unfortunately, you'll have to give a name to the anonymous class you're using.

Related

Trying to find the SQL statement that will return unique parcel number when given different portions of the property address in a web form

I have a table 'details' with 70 columns including property address info (column names include parcel_id, loc_strno, loc_strfrac, loc_strdir, loc_strname, loc_strtype, loc_strunit, loc_city, state, zip, country...) Users input address information in web form where form field represents column from dbsomething like INPUT =
loc_strno: 123
loc_strdir: West
loc_strname: Main
loc_strtype: Street
Desired OUTPUT: the parcel_id (Primary key of the table) matching the address 123 West Main Street = 555-45-6789
Not sure how to query the database. I am able to save the input address info but not sure of best way to use/compare it to get the parcel_id (primary key).
Web Form collecting address details
exports.postSearchedProperty = (req, res, next) => {
const loc_strno = req.body.loc_strno;
const loc_strfrac = req.body.loc_strfrac;
const loc_strdir = req.body.loc_strdir;
const loc_strname = req.body.loc_strname;
const loc_strtype = req.body.loc_strtype;
const loc_strunit = req.body.loc_strunit;
const loc_city = req.body.loc_city;
const state = req.body.state;
const zip = req.body.zip;
const country = req.body.country;
const searchedproperty = new SearchedProperty(null, loc_strno, loc_strfrac, loc_strdir, loc_strname, loc_strtype, loc_strunit,
loc_city, state, zip, country);
property
prior questions were helpful but not exact.
Mysql query to find ID where multiple condition meet for one column
SQL: how to select a single id ("row") that meets multiple criteria from a single column
What would be the problem with something like this?
SELECT parcel_id FROM dbsomething
WHERE loc_strno = ?
AND loc_strdir = ?
AND loc_strname = ?
AND loc_strtype = ?
Where, following your example inputs, the parameter values would be
'123'
'West'
'Main'
'Street'
EDIT
You have expressed that req.body has many properties and you don't know which will be defined. The best solution for this is to use JavaScript logic rather than SQL.
var queryList = [];
for (p in req.body) {
/* iterate through all possible attributes */
if (req.body[p] !== null) {
/* include the attribute in the query if it's defined */
queryList.push(p + ' = ?');
}
}
const query = 'SELECT parcel_id FROM dbsomething WHERE ' + queryList.join(' AND ');
You can follow a similar procedure to set the actual parameter values. By doing this, you can filter only by attributes that are defined.

insert data in multiple table with one function in laravel

I'm trying to add values in multiple tables with the same function but I get an error that the id and product_id can't be null !! even though they are set. Here's my code:
$parentproduct=new Product();
$parentproduct->id=Input::get('id');
$insertedId = $parentproduct->id;
$parentproduct->save();
$product=new ProductsTranslation();
$product->id=Input::get('id');
$product->product_id =Input::get('insertedId');
$product->title=Input::get('title');
$product->content=Input::get('content');
$product->price=Input::get('price');
$product->description_title=Input::get('description_title');
$product->prod_info_title=Input::get('prod_info_title');
$product->prod_info=Input::get('prod_info');
$product->save();
Looks like you need to move a few things around here...
This $insertedId = $parentproduct->id; wont return a value until you've ran `->save().
Also, your second statement is trying to get an Input::('insertedId') but you're setting a variable above.
Try this:
$parentproduct = new Product();
$parentproduct->id = Input::get('id');
$parentproduct->save();
$insertedId = $parentproduct->id;
$product = new ProductsTranslation();
$product->id = Input::get('id');
$product->product_id = $insertedId;
$product->title = Input::get('title');
$product->content = Input::get('content');
$product->price = Input::get('price');
$product->description_title = Input::get('description_title');
$product->prod_info_title = Input::get('prod_info_title');
$product->prod_info = Input::get('prod_info');
$product->save();

Include nested entity details but don't group by then when grouping by other fields

I working with Database first C# MVC, EF6, LINQ and JSon to try and pass data to both Highcharts and Google Maps for some of my reporting.
If I could add an image I would show you the relevant portion of my model, but sadly I need more reputation to do that...
The portion of the Entity Model I'm concentrating on right now is based on a central Docket that contains a BuildingCode as part of a one-to-many relationship to a building with and address and further relationship to the buildings polygons (for mapping). Dockets are also classified by one or more DocketTypes and thus there is a many-to-many relationship between Dockets and DocketTypes, which is not directly exposed to through the EF.
As an example a Docket which represents an investigation, could be related to the theft of a mobile phone in building A located on Campus X, not only was the cellphone stolen but the assailant also assaulted the victim in order to steal the mobile phone. So there are 2 DocketTypes here 1. Theft of mobile phone and 2. assault. Note: this is fictitious and for illustration purposes only .
One of my fundamental reports requires that I count how many docketTypes affect each building and each campus in a given period. When I display this I also need to show what the DocketTypes are.
I have no end of nightmare trying to find a way to get this right, I keep running into circular reference errors and needing to use explicit conversions when trying to model the data with LINQ so that I can pass a single nested object through JSON to the client side where displaying will occur.
In the below code I am told I need an Explicit conversion:
Cannot implicitly convert type 'Campus_Investigator.ViewModels.DocketTypeViewModel' to 'System.Collections.Generic.IEnumerable<Campus_Investigator.ViewModels.DocketTypeViewModel>'. An explicit conversion exists (are you missing a cast?)
var currentDocketQuery = from d in db.Dockets
from dt in d.DocketTypes
from bp in d.BuildingDetail.BuildingPolygons
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
select new CampusBuildingDocketTypeViewModel()
{
BuildingCode = d.BuildingDetail.BuildingCode,
BuildingName = d.BuildingDetail.BuildingName,
//BuildingPolygons = d.BuildingDetail.BuildingPolygons,
DocketTypes = new DocketTypeViewModel()
{
Category = dt.Category,
SubCategory = dt.SubCategory,
ShortDescription = dt.ShortDescription
}
};
I appreciate any ideas on how I can explicitly convert this or is that a better method I can use and avoid the circular reference error?
You included some redundant part in your query (which performs some inner join). The from bp in d.BuildingDetail.BuildingPolygons is joined in but then is not shown in the result. So it totally does not make sense. There may be duplicated elements in the result due to that. The from dt in d.DocketTypes is wrong joined in, although you need it in the result but because the DocketTypes is output per d in db.Dockets, so it's just simply queried like this:
var currentDocketQuery = from d in db.Dockets
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
select new CampusBuildingDocketTypeViewModel()
{
BuildingCode = d.BuildingDetail.BuildingCode,
BuildingName = d.BuildingDetail.BuildingName,
//BuildingPolygons = d.BuildingDetail.BuildingPolygons,
DocketTypes = d.DocketTypes
};
In fact I can see the commented line //BuildingPolygons = d.BuildingDetail.BuildingPolygons, so if you want to include that, it should also work.
If the DocketTypes has different type of d.DocketTypes, then you need a simple projection like this:
var currentDocketQuery = from d in db.Dockets
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
select new CampusBuildingDocketTypeViewModel()
{
BuildingCode = d.BuildingDetail.BuildingCode,
BuildingName = d.BuildingDetail.BuildingName,
//BuildingPolygons = d.BuildingDetail.BuildingPolygons,
DocketTypes = d.DocketTypes.Select(e => new DocketTypeViewModel()
{
Category = e.Category,
SubCategory = e.SubCategory,
ShortDescription = e.ShortDescription
})
};
I managed to solve this one by using the below. The major hassle with this is the circular referencing that exists in the model. When JSON serializes these, everything falls apart so it takes a lot of transforming to make sure that I only extract what I need. In this case grouped campus and building data (below includes the polygons which where only half commented out in the above) and then the include the detail of the DocketTypes that occurred at each building.
var datetime = DateTime.Now.AddDays(-30);
var campusDocket = from d in db.Dockets
where d.OccurrenceStartDate >= datetime && d.BuildingDetail.CampusName == Campus
group d by new { d.BuildingDetail.CampusName, d.BuildingDetail.BuildingCode, d.BuildingDetail.BuildingName } into groupdata
select new CampusBuildingDocketTypeViewModel
{
BuildingCode = groupdata.Key.BuildingCode,
BuildingName = groupdata.Key.BuildingName,
CampusName = groupdata.Key.CampusName,
Count = groupdata.Count(),
BuildingPolygons = from bp in db.BuildingPolygons
where bp.BuildingCode == groupdata.Key.BuildingCode
select new BuildingPolygonViewModel
{
Accuracy = bp.Accuracy,
BuildingCode = bp.BuildingCode,
PolygonOrder = bp.PolygonOrder,
Latitude = bp.Latitude,
Longitude = bp.Longitude
},
DocketTypes = from doc in db.Dockets
from dt in doc.DocketTypes
where doc.OccurrenceStartDate >= datetime && doc.BuildingCode == groupdata.Key.BuildingCode
select new DocketTypeViewModel
{
Category = dt.Category,
SubCategory = dt.SubCategory,
ShortDescription = dt.ShortDescription
}
};
The Answer again is ViewModels. I'm finding ViewModels seem to solve a lot of problems...

Adding of Generic Markers to tt_news - Database related

I am trying to write a custom output to extend the tt_news-Extension. I have suceeded so far as I have successfully written:
My own extension (via the help of extension builder)
Found a method to output some of my data via GENERIC Markers and TypoScript
What I want to do is:
Read Data from a MySQL Table (from my extensions preferably)
Compare data with a tt_news Column (Column contains VARCHAR "1,2,3,4")
Look for a certain UID (WHERE tt_news.txy7... CONTAINS uid )
Only output the objects found in the list.
Now I know I should probably build a relational database in the end, containing uid, fahrzeug.uid, tt_news.uid , but I'm really trying to figure out a way to output stuff first.
I think I have a basic thinking mistake in there, but I really need to take a break, since im working nearly 6 hours on this now.
Maybe someone could provide me with some directions?
# Output via Generic Markers
temp.fahrzeuge = CONTENT
temp.fahrzeuge {
table = tx_y7fahrzeugdatenbank_domain_model_fahrzeug
wrap = <div class="tx_y7fahrzeuge_ausgabe">|</div>
select {
selectFields = uid,name,beschreibung
# where = tt_news.tx_y7fahrzeugdatenbank_participate CONTAINS uid
}
renderObj = COA
renderObj {
10 = TEXT
10.wrap = <span class="fzname">|</span>
10.field = name
20 = TEXT
20.wrap = <span class="fzdesc">|</span>
20.field = beschreibung
}
}
plugin.tt_news.genericmarkers {
fzparticipate = COA
fzparticipate {
10 = TEXT
10.value = <h2>Fahrzeuge</h2>
20 = CONTENT
20 < temp.fahrzeuge.renderObj
}
#currentnews = plugin.tt_news.currentUid
}
1) add the whole template to your COA not only the renderObj:
fzparticipate = COA
fzparticipate {
10 = TEXT
10.value = <h2>Fahrzeuge</h2>
20 < temp.fahrzeuge
}
2) make sure you have a pid set for the objects you are selecting and that you in some way set the pidInList option within the select. The result will be empty if you don't!:
select {
#set your pid here
pidInList = 35
# selected fields
selectFields=uid
where = 1=1
}
3) You can add where-clauses in 2 ways: Where & andWhere
3.1) andWhere has a cObject which you can set
table = tx_myTable_mapping
select {
#Do not forget the pid!
pidInList = {$plugin.myPlugin.pid}
#did you know that you can use distinct here?
selectFields=DISTINCT(name)
#you can use a COA here as well, for more complex clauses
andWhere.cObject = TEXT
andWhere.cObject {
#This 3 lines come in handy to prevent SQLInjections
#by fully quoting the GET/POST variable
data = GP:myPostVariable
#tell the system for which table it should do the quoting
fullQuoteStr = tx_myTable_mapping
wrap = myTablefield=|
}
}
3.2) where supports data and wrap options
table = tx_myTable_mapping
select {
#you can do joins as well:
join = fe_users on tx_myTable_mapping.fe_user = fe_users.uid
#again with the pageId
pidInList = {$plugin.myPlugin.pid}
selectFields=tx_myTable_mapping.name as MyLabel
#you can set the where in a static way like you did
#or you use the data and wrap options
where.data = TSFE:fe_user|user|uid
where.wrap = (fe_users.uid = | )
}

Linq-to-SQL with a table valued UDF user defined function

I am new to Linq and trying to get a handle on how to bind a drop down to a SQL user defined function.
//Populate the Pledge dropdown
var db = new App_Data.MyDBDataContext();
int? partnerID = Convert.ToInt32(Request.QueryString["PartnerID"]);
var pledges =
from p in db.ufn_AvailablePledgesByPartner(partnerID)
select new
{
PledgeAndPartnerName = p.PledgeAndPartnerName,
PledgeID = p.PledgeID
};
DropDownList ddlPledgeID = (DropDownList)DetailsViewContribution.FindControl("DropDownListPledgeID");
ddlPledgeID.DataSource = pledges;
ddlPledgeID.DataTextField = pledges.PledgeAndPartnerName;
ddlPledgeID.DataValueField = pledges.PledgeID;
The current problem is the last 2 lines where I'm trying to reference properties of the anonymous class. "'System.Linq.IQueryable' does not contain a definition for 'PledgeAndPartnerName' and no extension method..." I naively thought the compiler was supposed to figure this out, but obviously I'm assuming C# is now more dynamic than it really is.
Thanks for any input.
Try this:
ddlPledgeID.DataTextField = "PledgeAndPartnerName";
ddlPledgeID.DataValueField = "PledgeID";