Linq to SQL including a db function - c#

I am trying to recover data from an SQL Server 2016 db.
To start, I have used the POCO class generator to create by datacontext, this contains a definition for the function I want to use.
// Table Valued Functions
[System.Data.Entity.DbFunction("DbContext", "GetData")]
[CodeFirstStoreFunctions.DbFunctionDetails(DatabaseSchema = "dbo")]
public IQueryable<GetDataReturnModel> GetData(long? Id)
{
var idParam = new System.Data.Entity.Core.Objects.ObjectParameter("ID", typeof(long)) { Value = Id.GetValueOrDefault() };
return ((System.Data.Entity.Infrastructure.IObjectContextAdapter)this).ObjectContext.CreateQuery<GetReturnModel>("[DbContext].[GetData](#ID)", opportunityIdParam);
}
Currently, I have to remove a dataset and then loop through the GetDataReturnedModel to populate the data from this function.
What I would like to do is recover this for each record along with the main request for data.
something like:
var data = Entities.Person
.Include("Address")
.Include(p => p.GetData(p.Id)
.ToList();
Is this possible?

Related

.Net Core query data from 2 different databases

I have a .Net Core project running and I am utilizing 2 different databases (A MySQL db and a PostGreSQL db). I have them set up and they are both implemented in my current controller - TripController.cs
TripController.cs
public IActionResult Index()
{
var viewModels = new List<TripViewModel>();
var Dids = _tripContext.Dids.ToList();
foreach (var Did in Dids)
{
IQueryAble<Tripmetadata> trips = _tripContext.Tripmetadata.Where(t => t.Did == Did.Did);
var tripsCount = trips.Count()
//--------------------- I believe error is here ---------------------
var alias = _context.Devices.Where(d => (long.Parse(d.Did)) == Did.Did).Select(d => d.Alias).ToString();
// ------------------------------------------------------------------
var viewModel = new TripViewModel
{
TripCount = tripsCount,
didElement = Did,
Alias = alias
};
viewModels.Add(viewModel)
}
return View(viewModels);
}
_context is the MySQL db and _tripContext is the PostGreSQL db.
Both database have a field called Did which I need to use. For the PostGreSQL db I need to use it to get the amount of trips (tripCount) for a given Did. However for the MySQL db I need to use the Did to get the alias for a device.
When I try to use the above code from the TripController to get the alias for a Did I get a weird value when displaying it in my view:
Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1[System.String]
as seen here:
I use a viewModel called TripViewModel which I pass to my View:
TripViewModel.cs
public class TripViewModel
{
public int TripCount {get;set;}
public long DidElement {get;set;}
public string Alias {get;set;}
}
How do I get it write the right Alias in my view?
I have tried numerous methods that doesn't yield the result I need.
I managed to find the solution.
My problem was not adding a .Single() at the end of my EF query.
I also found that this post is a duplicate. However I didn't know what my problem was until a stumpled upon this:

LINQ to Entities does not recognize the method ... method, and this method cannot be translated into a store expression.

MVC 5, C# -
I am creating a view model based upon different sets of data in my database. I have the following code to create the View Model.
public ActionResult Register_step6()
{
CoreGeneral cg = new CoreGeneral();
var model = (from p in db.WorkPointRoles
select new RegisterEmployee_Step6Model()
{
Role = p.Role,
Selected = false,
RoleDescription = cg.GetRoleDescription(p.Id)
});
return View(model);
}
I receive the following error message :
LINQ to Entities does not recognize the method 'System.String
GetRoleDescription(Int32)' method, and this method cannot be
translated into a store expression.
I understand that the message has something to do with the Entities not recognising my GetRoleDescription code because it is placed in the select statement - (I've porbably worded my understanding incorrectly).. anyway, how do I solve the problem, where can I put the GetRoleDescription so that it runs on every record returned?
I hope this makes sense to someone! Apologies for the poorly worded question. Thanks in advance!
You should perform projection to RegisterEmployee_Step6Model in-memory instead of SQL Server side.
public ActionResult Register_step6()
{
CoreGeneral cg = new CoreGeneral();
var model = (from p in db.WorkPointRoles
select p).AsEnumerable()
.Select(r => new RegisterEmployee_Step6Model()
{
Role = r.Role,
Selected = false,
RoleDescription = cg.GetRoleDescription(r.Id)
});
return View(model);
}

insert two object in database with linq

i have two sql table (master/detail) and i have one method that save the object in sql.
like this:
public int InsertDoc(MymasterModel _inputMstr, string _IsForsale)
{
MasterModel _Mstr = new MasterModel();
InsertDocs ins = new InsertDocs();
_Mstr.Date = _inputMstr.DocDate;
.
.
.
;
_Mstr.DtlsModel = new List<DtlDataModel>();
_inputMstr.MyDtlDataModel.ToList().ForEach(d =>
{
_Mstr.DtlsModel.Add(new DtlDataModel()
{
Serial = d.Serial.ToString(),
Qty = d.Qty,
...
});
});
<b>return ins.InsertDoc(_Mstr)</b>;
}
Now i want to save two docs with different type with same detail in sql. (Input and OutPut Doc)
insert this docs Linked to each other like transaction.
how can i do this with linq?
thanks a lot
As #BenRobinson mentioned up above, you can't do it with LINQ. LINQ is for Queries. You could look at Entity Framework (or another ORM) for doing Updates, Inserts, or Deletes.
EntityFramework would look something like:
var details=new details {...}
db.details.Add(details):
db.docs.Add(new doc {... , details=details});
db.docs.Add(new doc {... , detials=details});
db.SaveChanges();

MongoDB: update only specific fields

I am trying to update a row in a (typed) MongoDB collection with the C# driver. When handling data of that particular collection of type MongoCollection<User>, I tend to avoid retrieving sensitive data from the collection (salt, password hash, etc.)
Now I am trying to update a User instance. However, I never actually retrieved sensitive data in the first place, so I guess this data would be default(byte[]) in the retrieved model instance (as far as I can tell) before I apply modifications and submit the new data to the collection.
Maybe I am overseeing something trivial in the MongoDB C# driver how I can use MongoCollection<T>.Save(T item) without updating specific properties such as User.PasswordHash or User.PasswordSalt? Should I retrieve the full record first, update "safe" properties there, and write it back? Or is there a fancy option to exclude certain fields from the update?
Thanks in advance
Save(someValue) is for the case where you want the resulting record to be or become the full object (someValue) you passed in.
You can use
var query = Query.EQ("_id","123");
var sortBy = SortBy.Null;
var update = Update.Inc("LoginCount",1).Set("LastLogin",DateTime.UtcNow); // some update, you can chain a series of update commands here
MongoCollection<User>.FindAndModify(query,sortby,update);
method.
Using FindAndModify you can specify exactly which fields in an existing record to change and leave the rest alone.
You can see an example here.
The only thing you need from the existing record would be its _id, the 2 secret fields need not be loaded or ever mapped back into your POCO object.
It´s possible to add more criterias in the Where-statement. Like this:
var db = ReferenceTreeDb.Database;
var packageCol = db.GetCollection<Package>("dotnetpackage");
var filter = Builders<Package>.Filter.Where(_ => _.packageName == packageItem.PackageName.ToLower() && _.isLatestVersion);
var update = Builders<Package>.Update.Set(_ => _.isLatestVersion, false);
var options = new FindOneAndUpdateOptions<Package>();
packageCol.FindOneAndUpdate(filter, update, options);
Had the same problem and since I wanted to have 1 generic method for all types and didn't want to create my own implementation using Reflection, I end up with the following generic solution (simplified to show all in one method):
Task<bool> Update(string Id, T item)
{
var serializerSettings = new JsonSerializerSettings()
{
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore
};
var bson = new BsonDocument() { { "$set", BsonDocument.Parse(JsonConvert.SerializeObject(item, serializerSettings)) } };
await database.GetCollection<T>(collectionName).UpdateOneAsync(Builders<T>.Filter.Eq("Id", Id), bson);
}
Notes:
Make sure all fields that must not update are set to default value.
If you need to set field to default value, you need to either use DefaultValueHandling.Include, or write custom method for that update
When performance matters, write custom update methods using Builders<T>.Update
P.S.: It's obviously should have been implemented by MongoDB .Net Driver, however I couldn't find it anywhere in the docs, maybe I just looked the wrong way.
Well there are many ways to updated value in mongodb.
Below is one of the simplest way I choose to update a field value in mongodb collection.
public string UpdateData()
{
string data = string.Empty;
string param= "{$set: { name:'Developerrr New' } }";
string filter= "{ 'name' : 'Developerrr '}";
try
{
//******get connections values from web.config file*****
var connectionString = ConfigurationManager.AppSettings["connectionString"];
var databseName = ConfigurationManager.AppSettings["database"];
var tableName = ConfigurationManager.AppSettings["table"];
//******Connect to mongodb**********
var client = new MongoClient(connectionString);
var dataBases = client.GetDatabase(databseName);
var dataCollection = dataBases.GetCollection<BsonDocument>(tableName);
//****** convert filter and updating value to BsonDocument*******
BsonDocument filterDoc = BsonDocument.Parse(filter);
BsonDocument document = BsonDocument.Parse(param);
//********Update value using UpdateOne method*****
dataCollection.UpdateOne(filterDoc, document);
data = "Success";
}
catch (Exception err)
{
data = "Failed - " + err;
}
return data;
}
Hoping this will help you :)

How do I order a sql datasource of uniqueidentifiers in Linq by an array of uniqueindentifiers

I have a string list(A) of individualProfileId's (GUID) that can be in any order(used for displaying personal profiles in a specific order based on user input) which is stored as a string due to it being part of the cms functionality.
I also have an asp c# Repeater that uses a LinqDataSource to query against the individual table. This repeater needs to use the ordered list(A) to display the results in the order specified.
Which is what i am having problems with. Does anyone have any ideas?
list(A)
'CD44D9F9-DE88-4BBD-B7A2-41F7A9904DAC',
'7FF2D867-DE88-4549-B5C1-D3C321F8DB9B',
'3FC3DE3F-7ADE-44F1-B17D-23E037130907'
Datasource example
IndividualProfileId Name JobTitle EmailAddress IsEmployee
3FC3DE3F-7ADE-44F1-B17D-23E037130907 Joe Blo Director dsd#ad.com 1
CD44D9F9-DE88-4BBD-B7A2-41F7A9904DAC Maxy Dosh The Boss 1
98AB3AFD-4D4E-4BAF-91CE-A778EB29D959 some one a job 322#wewd.ocm 1
7FF2D867-DE88-4549-B5C1-D3C321F8DB9B Max Walsh CEO 1
There is a very simple (single-line) way of doing this, given that you get the employee results from the database first (so resultSetFromDatabase is just example data, you should have some LINQ query here that gets your results).
var a = new[] { "GUID1", "GUID2", "GUID3"};
var resultSetFromDatabase = new[]
{
new { IndividualProfileId = "GUID3", Name = "Joe Blo" },
new { IndividualProfileId = "GUID1", Name = "Maxy Dosh" },
new { IndividualProfileId = "GUID4", Name = "some one" },
new { IndividualProfileId = "GUID2", Name = "Max Walsh" }
};
var sortedResults = a.Join(res, s => s, e => e.IndividualProfileId, (s, e) => e);
It's impossible to have the datasource get the results directly in the right order, unless you're willing to write some dedicated SQL stored procedure. The problem is that you'd have to tell the database the contents of a. Using LINQ this can only be done via Contains. And that doesn't guarantee any order in the result set.
Turn the list(A), which you stated is a string, into an actual list. For example, you could use listAsString.Split(",") and then remove the 's from each element. I’ll assume the finished list is called list.
Query the database to retrieve the rows that you need, for example:
var data = db.Table.Where(row => list.Contains(row.IndividualProfileId));
From the data returned, create a dictionary keyed by the IndividualProfileId, for example:
var dic = data.ToDictionary(e => e.IndividualProfileId);
Iterate through the list and retrieve the dictionary entry for each item:
var results = list.Select(item => dic[item]).ToList();
Now results will have the records in the same order that the IDs were in list.

Categories