Select single value from db - sql-server

I need to select a single value from my db.
MyController.cs
using (var db = new MainDbContext())
{
var getPhoto = db.Users.Where(u => u.Name == User.Identity.Name).Select(u => u.Photo);
var materializePhoto = getPhoto.ToList();
var photo = materializePhoto[0];
}
I do this stuff in order to properly convert my value from IQueryable to String.
I've read about using 'FirstOrDefault', 'First', 'Default' select options (cause they return a string value, not IQuerable) but I think it isn't suitable for my case.
The question is: how can I make my code simplier and shorter?
P.S.: db.Users.Photo contains url's.

You need to add FirstOrDefault to your code
var getPhoto = db.Users.Where(u => u.Name == User.Identity.Name).Select(u => u.Photo).FirstOrDefault();
and yes, it will work.

You could do like this also
var photo = db.Users.Where(u => u.Name == User.Identity.Name).FirstOrDefault().Photo;
It will also return the first photo value

Please use FirstOrDefault() to select single record from db.

Related

Get specific columns on an Included Entity: Invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'

One of my linked tables PropertyInfo has an image column, which I don't want to retrieve, every time I .Include() that table. Therefore I took the following approach:
user = _context.Users.Where(x => x.Id == idOfUser)
.Include(x => x.Co.PropertyInfo.Select(i =>
new PropertyModel(
Id = i.Id,
Date = i.Date,
CompanyNumber = i.CompanyNumber,
LinkedCategories = i.LinkedCategories,
LinkedReviews = i.LinkedReviews)))
.ThenInclude(x => x.LinkedCategories)
.ThenInclude(x => x.LinkedReviews)))
.Take(1)
.FirstOrDefault()
This code throws an error:
The expression [EXPRESSION I PASTED ABOVE] is invalid inside an 'Include' operation, since it does not represent a property access: 't => t.MyProperty'....
Is it possible that I'm trying to assign the linked Tables like LinkedCategories and LinkedReviews which are being ThenInclud-ed? Or is this related to something else? How can I include entities without querying for all of the columns?
Maybe something like this if you have an empty constructor in PropertyModel.
You definitely can make it with single query. I don't know what is the structure of your models. For more accurate answer, you can share them.
user = _context.Users.Where(x => x.Id == idOfUser)
.Select(i => new PropertyModel
{
Id = i.PropertyInfo.Id,
Date = i.PropertyInfo.Date,
CompanyNumber = i.PropertyInfo.CompanyNumber,
LinkedCategories = i.PropertyInfo.LinkedCategories,
LinkedReviews = i.PropertyInfo.LinkedReviews
})
.Take(1)
.FirstOrDefault()

Dapper One to Many Mapping Logic

The dapper tutorial gives this example to help a user with Multi Mapping (One to Many)
While this works I am curious why they have you store the orders in the dictionary but then in the end they use a linq.Distinct() and return from the list. It seems like it would be cleaner to just return the ordersDictionary.Values as the dictionary logic ensures no duplicates.
//Tutorial
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
Dictionary<int,Order> orderDictionary = new Dictionary<int, Order>();
List<Order> list = connection.Query<Order, OrderDetail, Order>(sql, (order, orderDetail) =>
{
if (!orderDictionary.TryGetValue(order.OrderID, out Order orderEntry))
{
orderEntry = order;
orderEntry.OrderDetails = new List<OrderDetail>();
orderDictionary.Add(orderEntry.OrderID, orderEntry);
}
orderEntry.OrderDetails.Add(orderDetail);
return orderEntry;
}, splitOn: "OrderID")
.Distinct()
.ToList();
return list;
}
//my suggestion
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
Dictionary<int,Order> orderDictionary = new Dictionary<int, Order>();
//change 1 no need to store into list here
connection.Query<Order, OrderDetail, Order>(sql, (order, orderDetail) =>
{
if (!orderDictionary.TryGetValue(order.OrderID, out Order orderEntry))
{
orderEntry = order;
orderEntry.OrderDetails = new List<OrderDetail>();
orderDictionary.Add(orderEntry.OrderID, orderEntry);
}
orderEntry.OrderDetails.Add(orderDetail);
return orderEntry;
}, splitOn: "OrderID"); //change 2 remove .Distinct().ToList()
return orderDictionary.Values.ToList(); //change 3 return dictionaryValues
}
I'm the author of this tutorial: https://dapper-tutorial.net/query#example-query-multi-mapping-one-to-many
why they have you store the orders in the dictionary
A row is returned for every OrderDetail. So you want to make sure to add the OrderDetail to the existing Order and not create a new one for every OrderDetail. The dictionary is used for performance to check if the Order has been already created or not.
it would be cleaner to just return the ordersDictionary.Values
How will your query return dictionary values?
Of course, if you are in a method such as yours, you can do
var list = orderDictionary.Values;
return list;
But how to make this Connection.Query return dictionary values? An order is returned for every row/OrderDetail, so the order will be returned multiple times.
Outside the Query, your dictionary solution works great and is even a better solution for performance, but if you want to make your Query return the distinct list of orders without using Distinct or some similar method, it's impossible.
EDIT: Answer comment
my suggestion return orderDictionary.Values.ToList(); //change 3 return dictionaryValues
Thank you for your great feedback, it's always appreciated ;)
It would be weird in a tutorial to use what the query returns when there is no relationship but use the dictionary for one to many relationships
// no relationship
var orders = conn.Query<Order>("", ...).Distinct();
// one to many relationship
conn.Query<Order, OrderDetail>("", ...);
var orders = orderDictionary.Values.ToList();
Your solution is better for performance the way you use it, there is no doubt about this. But this is how people usually use the Query method:
var orders = conn.Query("", ...).Distinct();
var activeOrders = orders.Where(x => x.IsActive).ToList();
var inactiveOrders = orders.Where(x => !x.IsActive).ToList();
They use what the Query method returns.
But again, there is nothing wrong with the way you do it, this is even better if you can do it.

How to set Query Parameters

How to map the OLE DB source SQL command query parameters with variables using EzAPI ?
Basically I need to do something like below.
Thanks in advance.
Here is how I had to do it for SSIS 2012. I had to find the GUID of the variable in question and set it that way.
EzOleDbSource source = new EzOleDbSource(this);
source.Connection = sourceconnection;
source.SqlCommand = sourcecomannd;
source.AccessMode = AccessMode.AM_SQLCOMMAND;
source.SetComponentProperty("ParameterMapping", "\"Parameter0:Input\",{C2BCD5B0-1FDB-4A74-8418-EEF9C1D19AC3};");
To get the GUID you can query the Variables in the EZPackage object.
Application a = new Application();
var package = a.LoadPackage(packagelocation, null);
var ezpackage = new EzPackage(package);
var firstOrDefault = ezpackage.Variables.OfType<Microsoft.SqlServer.Dts.Runtime.Variable>()
.AsQueryable()
.FirstOrDefault(x => x.Name.Equals("MyParameter"));
if (firstOrDefault != null)
{
var guid =
firstOrDefault.ID;
}
I have accepted Geek's answer because it is the real answer for my question. But I found instead of mapping variables to parameters we can use variables directly in the query. For example: exec your_sp_name "#[User::your_variable_name]"
UPDATE : Above method is not working.
Use the the accepted answer method. To take the GUID of the variable, I used the follwing method.
string guid = string.Empty;
foreach (var x in this.Variables)
{
if (x.Name == "cdc_capture_log_id")
{
guid = x.ID;
}
}
Where this = EzPackage. Same as above.

Audit of what records a given user can see in SalesForce.com

I am trying to determine a way to audit which records a given user can see by;
Object Type
Record Type
Count of records
Ideally would also be able to see which fields for each object/record type the user can see.
We will need to repeat this often and for different users and in different orgs, so would like to avoid manually determining this.
My first thought was to create an app using the partner WSDL, but would like to ask if there are any easier approaches or perhaps existing solutions.
Thanks all
I think that you can follow the documentation to solve it, using a query similar to this one:
SELECT RecordId
FROM UserRecordAccess
WHERE UserId = [single ID]
AND RecordId = [single ID] //or Record IN [list of IDs]
AND HasReadAccess = true
The following query returns the records for which a queried user has
read access to.
In addition, you should add limit 1 and get from record metadata the object type,record type, and so on.
I ended up using the below (C# using the Partner WSDL) to get an idea of what kinds of objects the user had visibility into.
Just a quick'n'dirty utility for my own use (read - not prod code);
var service = new SforceService();
var result = service.login("UserName", "Password");
service.Url = result.serverUrl;
service.SessionHeaderValue = new SessionHeader { sessionId = result.sessionId };
var queryResult = service.describeGlobal();
int total = queryResult.sobjects.Count();
int batcheSize = 100;
var batches = Math.Ceiling(total / (double)batcheSize);
using (var output = new StreamWriter(#"C:\test\sfdcAccess.txt", false))
{
for (int batch = 0; batch < batches; batch++)
{
var toQuery =
queryResult.sobjects.Skip(batch * batcheSize).Take(batcheSize).Select(x => x.name).ToArray();
var batchResult = service.describeSObjects(toQuery);
foreach (var x in batchResult)
{
if (!x.queryable)
{
Console.WriteLine("{0} is not queryable", x.name);
continue;
}
var test = service.query(string.Format("SELECT Id FROM {0} limit 100", x.name));
if(test == null || test.records == null)
{
Console.WriteLine("{0}:null records", x.name);
continue;
}
foreach (var record in test.records)
{
output.WriteLine("{0}\t{1}",x.name, record.Id);
}
Console.WriteLine("{0}:\t{1} records(0)", x.name, test.size);
}
}
output.Flush();
}

SqlCacheDependecy command notification not working

I been trying to get sqlcachedependecy working, but it doesn't appear to work
I got the proper settings in my web.config and also global.asa, however when I run this query and the changes are made to the database from either with in or outside the web site the cached objects are not updated please someone help? I know its not because this query is querying a view, because I tested this using straight SqlDependecy and the notification works fine.
public IQueryable<VictoryList> GetVictoryList()
{
string cacheKey = HttpContext.Current.User.Identity.Name + "victoryCacheKey";
IQueryable<VictoryList> cachednews = (IQueryable<VictoryList>)HttpContext.Current.Cache.Get(cacheKey);
if (cachednews == null)
{
var results = from v in _datacontext.ViewVictoryLists
orderby _datacontext.GetNewId()
select new VictoryList
{
MemberID = v.MemberID,
Username = v.Aspnetusername,
Location = v.Location,
DaimokuGoal = v.DaimokuGoal,
PreviewImageID = v.PreviewImageID,
TotalDaimoku = v.TotalDaimoku,
TotalDeterminations = v.TotalDeterminations,
DeterminationID = v.DeterminationID,
DeterminationName = v.DeterminationName
};
results = results.ToList().AsQueryable();
SqlCacheDependencyAdmin.EnableNotifications(_datacontext.Connection.ConnectionString);
SqlCacheDependency dependency =
new SqlCacheDependency(_datacontext.GetCommand(results) as SqlCommand);
HttpContext.Current.Cache.Insert(cacheKey, results, dependency);
return results;
}
return cachednews;
}
According to the stated Limitations for creating a query for notification, listed at msdn...
The statement must not reference a view.

Resources