LINQPad "native" connection to local Windows Search/oledb database - oledb

I'm trying to use LINQPad to connect to my local Windows Search index. I'm able to connect manually using code as described here: https://forum.linqpad.net/discussion/2060/connection-to-windows-search:
using (var connection = new OleDbConnection ("Provider=Search.CollatorDSO;Extended Properties=\"Application=Windows\""))
{
connection.Open();
var cmd = connection.CreateCommand();
cmd.CommandText = #"SELECT TOP 10 System.ItemPathDisplay, System.ItemUrl FROM SYSTEMINDEX WHERE System.ItemType = '.config'";
cmd.ExecuteReader().Dump(); // LINQPad lets you Dump a DataReader
}
I'm hoping that by now there's a way to do it using the native LINQPad connections. I played around a little with the 3rd-party "LINQ to DB" driver but haven't been successful. Anyone know how to do this? Thanks!

Joe Albahari (LINQPad creator) confirmed that there's no driver for this. Here's what I came up with instead, using the Dapper and System.Data.OleDb nuget packages:
const string defaultActivityQuery = #"SELECT
System.ActivityHistory.AppId,
System.ActivityHistory.AppActivityId,
System.ActivityHistory.StartTime,
System.ActivityHistory.EndTime,
System.ActivityHistory.ActiveDuration,
System.Activity.AppDisplayName,
System.Activity.ContentUri,
System.Activity.Description,
System.Activity.DisplayText,
System.Activity.AppImageUri,
System.Activity.BackgroundColor
FROM SystemIndex
WHERE (System.Activity.ActivityId IS NOT NULL) AND (System.ActivityHistory.StartTime > {0})
ORDER BY System.ActivityHistory.EndTime DESC";
...
var activities = WinSearch(string.Format(defaultActivityQuery, DateTime.Today.AddDays(-1).ToFileTimeUtc()));
...
static List<ActivityRecord> WinSearch(string query)
{
using OleDbConnection oleDbConnection = new OleDbConnection("Provider=Search.CollatorDSO;Extended Properties=\"Application=Windows\"");
var results = oleDbConnection.Query(query);
return JsonConvert.DeserializeObject<List<ActivityRecord>>(JsonConvert.SerializeObject(results));
}
public class ActivityRecord
{
[JsonProperty("SYSTEM.ACTIVITYHISTORY.APPID")]
public string? AppId { get; set; }
[JsonProperty("SYSTEM.ACTIVITYHISTORY.STARTTIME")]
public string? StartTimeString
{
set => this.StartTime = double.TryParse(value, out double result) ? DateTime.FromFileTimeUtc((long)result).ToLocalTime() : null;
}
public DateTime? StartTime { get; private set; }
[JsonProperty("SYSTEM.ACTIVITYHISTORY.ENDTIME")]
public string? EndTimeString
{
set => this.EndTime = double.TryParse(value, out double result) ? DateTime.FromFileTimeUtc((long)result).ToLocalTime() : null;
}
public DateTime? EndTime { get; private set; }
[JsonProperty("SYSTEM.ACTIVITYHISTORY.ActiveDuration")]
public string? ActiveDurationString
{
set => this.ActiveDuration = double.TryParse(value, out double result) ? TimeSpan.FromTicks((long)result) : null;
}
public TimeSpan? ActiveDuration { get; private set; }
public TimeSpan? Duration => this.EndTime - this.StartTime;
[JsonProperty("SYSTEM.ACTIVITY.APPDISPLAYNAME")]
public string? AppDisplayName { get; set; }
[JsonProperty("SYSTEM.ACTIVITY.ContentUri")]
public string? ContentUri { get; set; }
[JsonProperty("SYSTEM.ACTIVITY.DESCRIPTION")]
public string? Description { get; set; }
[JsonProperty("SYSTEM.ACTIVITY.DISPLAYTEXT")]
public string? DisplayText { get; set; }
[JsonProperty("SYSTEM.ACTIVITYHISTORY.APPACTIVITYID")]
public string? AppActivityId { get; set; }
}
Hope this helps someone else!

Related

Results of sql query are not shown correct in .net API

I have an sql query that calls a stored-procedure.
The stored-procedure is working properly in SQL server.However in .NET in foreach (var item in query_pre) part I get a wrong result.
In .NET. I have the following code:
public partial class get_active_call_info_ids
{
public int call_id { get; set; }
public List<int> call_info_id { get; set; }
public int call_info_timing_id { get; set; }
public List<System.DateTime> dateOfBirth { get; set; }
public List<string> patientName { get; set; }
public List<string> patientId { get; set; }
public string station_name { get; set; }
public get_active_call_info_ids()
{
call_info_id = new List<int>();
dateOfBirth = new List<System.DateTime>();
patientName = new List<string>();
patientId = new List<string>();
}
}
public class CallRootObject
{
public List<get_active_call_info_ids> Calls { get; set; }
public int StatusCode { get; set; }
public CallRootObject()
{
Calls = new List<get_active_call_info_ids>();
}
}
var query_pre = entities.Database.SqlQuery<get_active_call_info_id_Result>("exec [dbo].[get_active_call_info_id] #user_id", new SqlParameter("user_id", u_id))
.ToList();
//Create objects of classes to handle information
var queryItem = new get_active_call_info_ids();
var queryItems = new CallRootObject();
//Initialize parameters
int call_id_local = query_pre[0].call_id;
int previous_call_id_local = query_pre[0].call_id;
//Counter to control data manipulation
foreach (var item in query_pre)
{
call_id_local = item.call_id;
//System.Diagnostics.Debug.WriteLine(item.ToString());
queryItem.call_info_id.Clear();
queryItem.patientId.Clear();
queryItem.patientName.Clear();
queryItem.dateOfBirth.Clear();
}
queryItem.call_id = item.call_id;
queryItem.call_info_id.Add(item.call_info_id);
queryItem.call_info_timing_id = item.call_info_timing_id;
queryItem.patientId.Add(item.patientId);
queryItem.patientName.Add(item.patientName);
queryItem.dateOfBirth.Add(item.dateOfBirth);
queryItem.station_name = item.station_name;
};
My stored-procedure in SQL server is working fine:
However, the result of the API is the following:
"{\"Calls\":[{\"call_id\":91390,\"call_info_id\":[20],\"call_info_timing_id\":30,\"dateOfBirth\":[\"2020-09-23T17:54:04.817\"],\"patientName\":[\"N/A\"],\"patientId\":[\"987654\"],\"station_name\":\"ΣΤΑΘΜΟΣ ΠΑΛΙΟΥ ΝΟΣ. ΛΕΜΕΣΟΥ\"},{\"call_id\":91391,\"call_info_id\":[20],\"call_info_timing_id\":30,\"dateOfBirth\":[\"2020-09-23T17:54:04.817\"],\"patientName\":[\"N/A\"],\"patientId\":[\"987654\"],\"station_name\":\"ΣΤΑΘΜΟΣ ΠΑΛΙΟΥ ΝΟΣ. ΛΕΜΕΣΟΥ\"}],\"StatusCode\":1}"
I found the solution. Instead of having
queryItem.call_info_id.Clear();
queryItem.patientId.Clear();
queryItem.patientName.Clear();
queryItem.dateOfBirth.Clear();
I used:
queryItem = new get_active_call_info_ids();

How do you write a join statement when using FromSqlRaw in Entity Framework Core?

I am converting an existing application and I am using the existing database structure.
This is the model of the data I am querying:
public partial class StaffNotes
{
public int RecordNumber { get; set; }
public double? ContactNumber { get; set; }
public double? WriteNumber { get; set; }
public double? ToStaff { get; set; }
public double? FromStaff { get; set; }
public string Note { get; set; }
public DateTime? CriticalDate { get; set; }
public DateTime? NoteDate { get; set; }
public int? TicketNumber { get; set; }
public bool Imp { get; set; }
}
Instead of displaying the number of the ToStaff, I would like to display the appropriate name.
I have written the following query:
var staffNotes = _context.StaffNotes.FromSql("Select s.record_number, s.contact_number, s.To_Staff, s.From_Staff, s.Note_Date, s.Ticket_Number, s.Imp, s.Critical_Date, S.Note, s.write_number, c.first_name, c.last_name from staffnotes s, contacts c where s.contact_number = c.contact_number and s.Contact_Number = " + id).ToList();
My code runs and I'm not getting any errors. The only issue is the first_name and last_name do not appear in the data.
Is this because it is not part of the model? Is there a way to get around this?
I added the missing properties and it is now working.
you must use FromSqlRaw with using Microsoft.EntityFrameworkCore; instead of FromSql
var staffNotes = _context.StaffNotes.FromSqlRaw("Select s.record_number, s.contact_number, s.To_Staff, s.From_Staff, s.Note_Date, s.Ticket_Number, s.Imp, s.Critical_Date, S.Note, s.write_number, c.first_name, c.last_name from staffnotes s, contacts c where s.contact_number = c.contact_number and s.Contact_Number = " + id).ToList();

Don't know how to set Web API, problem to retrieve the data

I had this problem few days ago, And thought that I'd found the solution which was
setting lazy loading : false.
but my problem to retrieve the data persisted.
Using fiddler, or a front-end app I can't retrieve the data and as result I have only has values like : $ref=6
I think it is some kind of general setting problem, so I'm going to give some information here.
controller:
[AllowAnonymous]
[HttpGet]
[Route("GetQuestionsByTestId/{id}")]
public ICollection<Question> GetQuestionsByTestId(int id)
{
return db.Questions.Where(t => t.TestId == id)
.Include(a => a.Answers)
.Include(q=>q.Test)
.Include(q=>q.Test.TestType)
.ToList();
}
identityModels:
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
this.Configuration.LazyLoadingEnabled = false; //false for Lazy Loading Off
this.Configuration.ProxyCreationEnabled = false;
}
WebApiConfig:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
question Model:
[Table("Question")]
public class Question
{
public Question()
{
Answers = new HashSet<Answer>();
}
[Key]
public int QuestionId { get; set; }
[Required]
public string Name { get; set; }
public string Comment { get; set; }
public int Difficulty { get; set; }
public byte Repeat { get; set; } // 0 - 255
public bool IsLearned { get; set; }
public string QuestionNumber { get; set; }
public virtual ICollection<Answer> Answers { get; set; }
[ForeignKey("Chapter")]
public int ChapterId { get; set; }
public Chapter Chapter { get; set; }
[ForeignKey("Test")]
public int TestId { get; set; }
public Test Test { get; set; }
}
my return retrieved with chrome NETWORK: this is where my problem is:
[{$id: "1", QuestionId: 5, Name: "11", Comment: null, Difficulty: 0, Repeat: 0,
IsLearned: false,…},…]
0: {$id: "1", QuestionId: 5, Name: "11", Comment: null, Difficulty: 0, Repeat: 0,
IsLearned: false,…}
1: {$ref: "6"}
second object is not visible, there is only this: $ref:"6"
Please help, losing hope here.
I'm guessing here that you're using Entity Framework to store and retrieve data. Realistically you don't want to be returning data/entities straight from your database, you probably want to map your data into a set of classes called Data Transfer Objects (DTO).
You can do this manually or using a tool such as AutoMapper.
Manually you would do something like this
Create a DTO class:
public class QuestionDTO
{
public int QuestionId { get; set; }
public string Name { get; set; }
public string Comment { get; set; }
public int Difficulty { get; set; }
public byte Repeat { get; set; } // 0 - 255
public bool IsLearned { get; set; }
public string QuestionNumber { get; set; }
}
Change controller method:
[AllowAnonymous]
[HttpGet]
[Route("GetQuestionsByTestId/{id}")]
public IHttpActionResult GetQuestionsByTestId(int id)
{
var questions = db.Questions.Where(t => t.TestId == id)
.Include(a => a.Answers)
.Include(q => q.Test)
.Include(q => q.Test.TestType)
.ToList();
var questionDTOs = new List<QuestionDTO>();
foreach (var question in questions)
{
questionDTOs.Add(new QuestionDTO
{
QuestionId = question.QuestionId,
Name = question.Name,
Comment = question.Comment,
Difficulty = question.Difficulty,
Repeat = question.Repeat,
IsLearned = question.IsLearned,
QuestionNumber = question.QuestionNumber
});
}
return Ok(questionDTOs);
}
(I have changed the return type so that you can use the Ok method that will return a 200 message or if needed return other status codes such as 400 using BadRequest() etc)
Using DTOs allows you to control exactly what data is returned and you don't have to worry about changing things like Lazy loading or proxy creation

umbraco 7 insert row in custom table

I have just made a model and controller which insert new row in a custom table to my umbraco database.
I based it on petapoco tutorial http://creativewebspecialist.co.uk/2013/07/16/umbraco-petapoco-to-store-blog-comments/
Despite the script executing without errors the row is not inserted into the table.
here's what I have:
namespace MyImport.Models
{
[TableName("MyImport_Uploads")]
[PrimaryKey("ID", autoIncrement = true)]
[ExplicitColumns]
public class ImportFile
{
[Column("ID")]
[PrimaryKeyColumn(AutoIncrement=true)]
public int Id { get; set; }
[Required]
[Column("CompanyID")]
public string CompanyId { get; set; }
//public Guid CompanyId { get; set; }
[Required]
[Column("FilenameOriginal")]
public string FilenameOriginal { get; set; }
[Required]
[Column("Filename")]
public string Filename { get; set; }
[Required]
[Column("FileType")]
public string FileType { get; set; }
[Column("NumberOfItems")]
public int NumberOfItems { get; set; }
[Column("DateCreated")]
public DateTime DateCreated { get; set; }
[Column("DeleteExisting")]
public bool DeleteExisting { get; set; }
}
}
And controller:
namespace MyImport.Controllers
{
public class ImportController : SurfaceController
{
private Umbraco.Core.Persistence.UmbracoDatabase db = MyImport.Settings.UmbracoDbDSN;
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ImportExcel(ImportModel model)
{
var fileTypes = new List<string>
{
"text/xml",
"application/xml",
};
string fileType = GetFileType(model.FileUpload.ContentType);
if(model.FileUpload != null && model.FileUpload.ContentLength > 0)
{
string uploadDir = "~/imports";
string origFileName = model.FileUpload.FileName;
string extension = origFileName.Substring(origFileName.LastIndexOf('.') + 1);
string pathToCheck = Path.Combine(Server.MapPath(uploadDir), origFileName);
// Check to see if a file already exists with the
// same name as the file to upload.
if (!System.IO.File.Exists(pathToCheck))
{
string companyId = MyImport.Member.CompanyIdDummy;
string tempfileName = companyId.ToLower() + "-" + DateTime.Now.ToString("yyyyMMddHHmmss") + "." + extension;
pathToCheck = Path.Combine(Server.MapPath(uploadDir), tempfileName);
model.FileUpload.SaveAs(pathToCheck);
var importFile = new ImportFile
{
CompanyId = companyId,
Filename = tempfileName,
FilenameOriginal = origFileName,
FileType = extension,
DateCreated = DateTime.UtcNow
};
db.Insert(importFile);
}
TempData.Add("Success", true);
}
//redirect to current page to clear the form
return RedirectToCurrentUmbracoPage();
}
}
Any suggestions? Thanks
I had the database wrongly set up.
Basically I had it as umbraco.sdf in App_Data folder while I intended to use my full MSSQL database where the table was created.
I recreated the project, reinstalled umbraco and HAD to choose Customize at the bottom of the screen where I was choosing setting up cms access. This is important as I was then directed to the screen where I could set up my database connection.
Otherwise umbraco just install into SQL Server Express database which is stored in umbraco.sdf file in the project.
I hope this make sense for anyone looking for the solution to the same problem.

MVC 4 Web API NullException Error (Noobie)

I'm working on my first MVC 4 app, following the MVC First Web API Tutorial on Asp.net. I've left the names the same, but changed the model and controller code. Here's my model:
public class Product
{
public string SID { get; set; }
public string name { get; set; }
public string givenName { get; set; }
public string sn { get; set; }
public string mail { get; set; }
public string telephoneNumber { get; set; }
public string mobile { get; set; }
public string otherMobile { get; set; }
public string title { get; set; }
public string Manager { get; set; }
public DateTime whenChanged { get; set; }
}
public class ProductModel
{
public ProductModel()
{
ProductList = new List<Product>();
}
public IList<Product> ProductList { get; set; }
}
And here's my APIcontroller:
public class ProductsController : ApiController
{
ProductModel products = new ProductModel();
public IEnumerable<Product> GetAD()
{
DirectoryEntry domainRoot = new DirectoryEntry(LDAP_server);
DirectorySearcher searcher = new DirectorySearcher(searchStr);
SearchResultCollection results = searcher.FindAll();
foreach (SearchResult srchResult in results)
{
DirectoryEntry dirEntry = srchResult.GetDirectoryEntry();
if (dirEntry.Properties["givenName"].Value != null && dirEntry.Properties["sn"].Value != null && !dirEntry.Parent.Name.Contains("Terminated"))
{
products.ProductList.Add(new Product()
{
SID = dirEntry.Properties["sid"].Value.ToString(),
name = dirEntry.Properties["name"].Value.ToString(),
givenName = dirEntry.Properties["givenName"].Value.ToString(),
sn = dirEntry.Properties["sn"].Value.ToString(),
mail = dirEntry.Properties["mail"].Value.ToString(),
telephoneNumber = dirEntry.Properties["telephoneNumber"].Value.ToString(),
mobile = dirEntry.Properties["mobile"].Value.ToString(),
otherMobile = dirEntry.Properties["otherMobile"].Value.ToString(),
title = dirEntry.Properties["title"].Value.ToString(),
Manager = dirEntry.Properties["Manager"].Value.ToString(),
whenChanged = Convert.ToDateTime(dirEntry.Properties["whenChanged"].Value.ToString()),
});
}
}
return products.ProductList;
}
}
I'm getting the NullException on 'products.ProductList.Add(new Product()', am I missing something simple? Please forgive my coding, as I'm just trying to get this up and running, thanks.
the problem mostly likely is dealing with dirEntry, not Web API itself. rather than introduce LDAP into this, just create a bunch of dummy products to return.
FYI... there is also a memory leak issue with the use of LDAP objects. They need to be properly disposed of, both along the happy path and if an exception is thrown.
I'm an idiot. 'sid' is not the correct property name from AD, it is 'objectSid', thus always returning a null. I knew it was something simple.

Resources