Linq where a record contains 2 matched fields - vb.net

I’m working with an existing database with a design I’m not in control of, I’m using EF4, and querying using LINQ. I work in VB.Net but would be quite happy to translate a c# solution.
I would like to pull records from a table where two of the fields match a pair of items from a list.
So i have a list of
Public Class RequestInfo
Public Property INSP_ROUTINE_NM As String
Public Property FEATURE_ID As String
End Class
And I would like to query a table and pull any records where both INSP_ROUTINE_NM and FEATURE_ID match one of the Request Info items.
I can use contains easy enough on either of the fields
Dim Features = (From F In MLDb.TBL_FeatureInfoSet _
Where (C_Request.Select(Function(x) x.INSP_ROUTINE_NM)).Contains(F.INSP_ROUTINE_NM) Select F.FEATURE_ID, F.FEATURE_RUN_NO, F.INSP_ROUTINE_NM).ToList
I could use two contains calls but that would pull any record where both records match somewhere in the list not necessarily any one pair from the request.

You can try this:
C#
var Features= (from f in MLDb.TBL_FeatureInfoSet
let q = C_Request.Select(x=>x.INSP_ROUTINE_NM)
where q.Contains(f.INSP_ROUTINE_NM) || q.Contains(f.INSP_ROUTINE_NM)
// where q.Contains(f.INSP_ROUTINE_NM) && q.Contains(f.INSP_ROUTINE_NM)
select new {f.FEATURE_ID, f.FEATURE_RUN_NO}).ToList();

Related

Sitefinity - Safely delete orphaned dynamic content records

I've been adding records to a dynamic module via the API and in the process during my experimentation I added a bunch of records that weren't associated correctly with any valid parent record.
I've checked and so far I can see that Sitefinity stores data about these records in a number of tables:
mydynamiccontenttype_table
sf_dynamic_content
sf_dynmc_cntnt_sf_lnguage_data
sf_dynmc_cntent_sf_permissions
I would like to clean up the database by deleting these records but I want to make sure I don't create more problems in the process.
Anyone know if there are more references to these dynamic content type records or a process to safely delete them?
There are probably other tables, so your safest option would be to delete the items using the Sitefinity API.
Just get the masterId of the item and use a code like this:
public static void DeleteDataItemOfType(this DynamicModuleManager manager, string type, Guid Id)
{
Type resolvedType = TypeResolutionService.ResolveType(type);
using (var region = new ElevatedModeRegion(manager))
{
manager.DeleteDataItem(resolvedType, Id);
manager.SaveChanges();
}
}

SharePoint change column id for REST requests

I recently started experimenting with the REST API for SharePoint 2013 Foundation and I am trying to return all entries in a list. My GET request returns the data I am looking for, but the IDs used to identify the columns in the list are not helpful for identifying what the information is (see images below). The column IDs between 'Title' and 'ID', in the second image, are a jumble of characters.
SharePoint List View
Response Data
Is there any way to configure the list to use the column names as IDs? Also, is there some significance to the characters currently used as IDs?
You will need to make a second request to get a listing of columns that includes the InternalName and the Title which is what you are trying to reference:
You can use this REST call:
_api/web/lists/GetByTitle('Project Details')/fields
or you can use CSOM:
using (ClientContext context = new ClientContext(url))
{
List list = context.Web.Lists.GetByTitle("Project Details");
context.Load(list, l => l.Fields);
context.ExecuteQuery();
foreach(Field field in list.Fields)
{
Console.WriteLine(field.Title);
Console.WriteLine(field.InternalName);
}
}
SharePoint automatically generates the InternalName and it is a read-only field, at least using REST. It'll be easier to get the Field Data to correlate the InternalName to the Title than changing the values.
The column you are referring to, between Title and Id, is the ID of the content type associated to the item. It is not a column ID.
The SharePoint REST API is OData compliant, so you can use the $select parameter to query for the neccesary fields.
http://server/site/_api/web/lists('guid')/items?$select=Column1,Column2
Please be aware though, lookup fields need to be expanded as well, otherwise you get only the Id of the lookup item.
http://server/site/_api/web/lists('guid')/items?$select=LookupColumn&$expand=LookupColumn/Title

Using lucene to search data differently for different users conditionally

Consider that the entities that I need to perform text search are as following
Sample{
int ID, //Unique ID
string Name,//Searchable field
string Description //Searchable field
}
Now, I have several such entities which are commonly shared by all the users but each user can associate different tags, Notes etc to any of these entities. For simplicity lets say a user can add tags to a Sample entity.
UserSampleData{
int ID, //Sample ID
int UserID, //For condition
string tags //Searchable field
}
When a user performs search, I want to search for the given string in the fields Name, Description and tags associated to that Sample by the current user. I am pretty new to using lucene indexing and I am not able to figure how can I design a index and also the queries for such a situation. I need the results sorted on the relevance with the search query. Following approaches crossed my mind, but I have a feeling there could be better solutions:
Separately query 2 different entities Samples and UserSampleData and somehow mix the 2 results. For the results that intersect, we need to combine the match scores by may be averaging.
Flatten out the data by combining both the entities => multiple entries for same ID.
You could use a JoinUtil Lucene class but you must rename the second "ID" field of UserDataSample document into SAMPLE_ID (or another name different from "ID").
Below an example:
r = DirectoryReader.open(dir);
final Version version = Version.LUCENE_47; // Your lucene version
final IndexSearcher searcher = new IndexSearcher(r);
final String fromField = "ID";
final boolean multipleValuesPerDocument = false;
final String toField = "SAMPLE_ID";
String querystr = "UserID:xxxx AND yourQueryString"; //the userID condition and your query String
Query fromQuery = new QueryParser(version, "NAME", new WhitespaceAnalyzer(version)).parse(querystr);
final Query joinQuery = JoinUtil.createJoinQuery(fromField, multipleValuesPerDocument, toField, fromQuery, searcher, ScoreMode.None);
final TopDocs topDocs = searcher.search(joinQuery, 10);
Check the bug https://issues.apache.org/jira/browse/LUCENE-4824). I don't know if the bug is automatically solved into the current version of LUCENE otherwise I think you must convert the type of your ID fields to String.
I think that you need Relational Data. Handling relational data is not simple with Lucene. This is a useful blog post for.

Need a concept on fetching data with HQL while three or more tables are in use

A small briefing on what I am trying to do.
I have three tables Content(contentId, body, timeofcreation), ContentAttachmentMap(contentId, attachmentId) and Attachment(attachmentId, resourceLocation).
The reason I adopted to create the mapping table because in future application the attachment can also be shared with different content.
Now I am using HQL to get data. My objectives is as follows:
Get All contents with/without Attachments
I have seen some examples in the internet like you can create an objective specific class (not POJO) and put the attribute name from the select statement within its constructor and the List of that Class object is returned.
For e.g. the HQL will be SELECT new com.mydomain.myclass(cont.id, cont.body) ..... and so on.
In my case I am looking for the following SELECT new com.mydomain.contentClass(cont.id, cont.body, List<Attachment>) FROM ...`. Yes, I want to have the resultList contain contentid, contentbody and List of its Attachments as a single result List item. If there are no attachments then it will return (cont.id, contentbody, null).
Is this possible? Also tell me how to write the SQL statements.
Thanks in advance.
I feel you are using Hibernate in a fundamentally wrong way. You should use Hibernate to view your domain entity, not to use it as exposing the underlying table.
You don't need to have that contentClass special value object for all these. Simply selecting the Content entity serves what you need.
I think it will be easier to have actual example.
In your application, you are not seeing it as "3 tables", you should see it as 2 entities, which is something look like:
#Entity
public class Content {
#Id
Long id;
#Column(...)
String content;
#ManyToMany
#JoinTable(name="ContentAttachmentMap")
List<Attachment> attachments;
}
#Entity
public class Attachment {
#Id
Long id;
#Column(...)
String resourceLocation
}
And, the result you are looking for is simply the result of HQL of something like
from Content where attachments IS EMPTY
I believe you can join fetch too in order to save DB access:
from Content c left join fetch c.attachments where c.attachments IS EMPTY

Entity Framework 4.2 table per hierarchy group by discriminator

I am working on a project using an EF 4.2 code first model. This model contains a TPH inheritance structure for products. I need to group the polymorphic results of this inheritance model on the discriminator and am running into some issues.
The entity framework does not expose the discriminator to complete this grouping. My first question is can I get direct access to this discriminator? My reading and experience is telling me no, so I came up with this solution that sort of works. It is not performing well and I am not happy with how it will need to be maintained.
My classes look something like this (simplified):
Public MustInherit Class Product
<key()>
Public Property ProductID as integer
<StringLength(50, ErrorMessage:="Max 50 characters")>
<Required(ErrorMessage:="Product name is required")>
Public Property Name as String
<TimeStamp()>
Public Property Time_Stamp as DateTime = DateTime.Now()
End Class
Public Class Desktop
Inherits Product
<StringLength(50, ErrorMessage:="Max 50 characters")>
<Required(ErrorMessage:="Processor is required")>
Public Property Processor as String
End Class
Public Class Monitor
Inherits Product
<Required(ErrorMessage:="Monitor size is required")>
Public Property Size_Inches as Integer
End Class
I built an extension method that takes a product and returns it's basetype name as a string.
<Extension()>
Public Function ProductType(ByVal inProduct as Product) as String
ProductType = inProduct.GetType().BaseType.Name
End Function
With that, I built this structure to group the results of product by type so I can run through them:
Dim tmpProducts = db.Products.ToList()
Dim GrpProducts = tmpProducts.GroupBy(Function(prod) prod.ProductType) _
.Select(Function(s) New With {.ProductType = S.Key,
.Products = S })
I can now loop through the list to get the behavior I want, but the performance is not ideal and I am concerned it will be unacceptable as the number of products grows.
For Each ProductGroup in GrpProducts
Dim TypeName as String = ProductGroup.ProductType
Dim TypeProducts = ProductGroup.Products
Next
Also, this can give me easy access to shared properties (Name) but now I don't have many options to cast these into their real type, maybe a select case around TypeName. . .
Any recommendations are appreciated, also please forgive any code errors above, I retyped the examples from memory as I don't have access to the project at the moment.
A solution would be to model a bit more, and have a new entity ProductType having a property Name. Then you would have a simple 1-N relationship between Product and ProductType. I have not used EntityFramework, but with NHibernate you could easily make the framework always join that table on queries, so that it would not return a proxy for ProductType for each Product, which could harm performance.
As an add-on, in the future ProductType could develop other interesting properties (such as values that are common for every Product of that ProductType), so it adds flexibility to your solution, although it does have the immediate cost of adding another table to your database.
Following Linq query should get you a way to solve group by discriminator
from a in db.Records
group a.ID by new
{
Name= a is Audio ? "Audio" :
a is Video ? "Video" :
a is Picture ? "Picture" :
a is Document ? "Document" : "File"
} into g
select new
{
Name = g.Key.Name,
Total = g.Count()
}