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();
Related
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?
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:
I have entities stored in one table that look like (truncated here):
public class Record : TableEntity
{
public double Version;
public string User;
}
Basically, I want to retrieve all the RowKeys and only the Version column of the entire table (i.e. the entire first 2 columns). There is only one PartitionKey since there aren't too many entries. How can I programmatically retrieve these columns? I'm aware of query projection and have seen the example on the Azure site, but I don't know how to extend it for my purpose here.
Any help would be appreciated!
Please try the following code. Essentially you would need to specify the columns you wish to fetch in SelectColumns property of your query. I have not specified any filter criteria because you mentioned that the table doesn't contain that many entities.
static void QueryProjectionExample()
{
var cred = CloudStorageAccount.DevelopmentStorageAccount;
var client = cred.CreateCloudTableClient();
var table = client.GetTableReference("TableName");
var query = new TableQuery<DynamicTableEntity>()
{
SelectColumns = new List<string>()
{
"RowKey", "Version"
}
};
var queryOutput = table.ExecuteQuerySegmented<DynamicTableEntity>(query, null);
var results = queryOutput.Results;
foreach (var entity in results)
{
Console.WriteLine("RowKey = " + entity.RowKey + "; Version = " + entity.Properties["Version"].StringValue);
}
}
I'm trying to implement a text search option using the Lucene-based full-text search engine on my NHibernate-based MVC project (NHibernate.Search). All the documentation I've seen on how to do this suggests I need to look at specific columns for values, something like:
var query = "Title:Ford";
using (var search = NHibernate.Search.Search.CreateFullTextSession(s))
{
using (var transaction = s.BeginTransaction())
{
var carSearchResults = search.CreateFullTextQuery(query)
.SetMaxResults(5)
.List();
foreach(var car in carSearchResults)
{
Console.WriteLine(car.Title);
}
transaction.Commit();
}
}
I would rather look at all full-text indexed columns for the search string, like you can do in SQL with a wildcard on the FREETEXT function... so I could do something like:
var query = "Ford";
using (var search = NHibernate.Search.Search.CreateFullTextSession(s))
{
using (var transaction = s.BeginTransaction())
{
var carSearchResults = search.CreateFullTextQuery(query)
.SetMaxResults(5)
.List();
foreach(var car in carSearchResults)
{
Console.WriteLine(car.Title);
}
transaction.Commit();
}
}
... and this would examine all full-text indexed properties for "Ford", and return all hits. Is there a comparable function/ method/ syntax for this using the NHibernate-based search engine?
Take a look at How to incorporate multiple fields in QueryParser?
Short answer, change:
var query = "Title:Ford";
to:
var query = "Title:Ford OR Name:Ford OR Field1:Ford OR Field2:Ford"; // etc for all fields
I have a query that looks like this:
using (MyDC TheDC = new MyDC())
{
foreach (MyObject TheObject in TheListOfMyObjects)
{
DBTable TheTable = new DBTable();
TheTable.Prop1 = TheObject.Prop1;
.....
TheDC.DBTables.InsertOnSubmit(TheTable);
}
TheDC.SubmitChanges();
}
This query basically inserts a list into the database using linq-to-sql. Now I've read online that L2S does NOT support bulk operations.
Does my query work by inserting each element at a time or all of them in one write?
Thanks for the clarification.
I modified the code from the following link to be more efficient and used it in my application. It is quite convenient because you can just put it in a partial class on top of your current autogenerated class. Instead of InsertOnSubmit add entities to a list, and instead of SubmitChanges call YourDataContext.BulkInsertAll(list).
http://www.codeproject.com/Tips/297582/Using-bulk-insert-with-your-linq-to-sql-datacontex
partial void OnCreated()
{
CommandTimeout = 5 * 60;
}
public void BulkInsertAll<T>(IEnumerable<T> entities)
{
using( var conn = new SqlConnection(Connection.ConnectionString))
{
conn.Open();
Type t = typeof(T);
var tableAttribute = (TableAttribute)t.GetCustomAttributes(
typeof(TableAttribute), false).Single();
var bulkCopy = new SqlBulkCopy(conn)
{
DestinationTableName = tableAttribute.Name
};
var properties = t.GetProperties().Where(EventTypeFilter).ToArray();
var table = new DataTable();
foreach (var property in properties)
{
Type propertyType = property.PropertyType;
if (propertyType.IsGenericType &&
propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
propertyType = Nullable.GetUnderlyingType(propertyType);
}
table.Columns.Add(new DataColumn(property.Name, propertyType));
}
foreach (var entity in entities)
{
table.Rows.Add(
properties.Select(
property => property.GetValue(entity, null) ?? DBNull.Value
).ToArray());
}
bulkCopy.WriteToServer(table);
}
}
private bool EventTypeFilter(System.Reflection.PropertyInfo p)
{
var attribute = Attribute.GetCustomAttribute(p,
typeof(AssociationAttribute)) as AssociationAttribute;
if (attribute == null) return true;
if (attribute.IsForeignKey == false) return true;
return false;
}
The term Bulk Insert usually refers to the SQL Server specific ultra fast bcp based SqlBulkCopy implementation. It is built on top of IRowsetFastLoad.
Linq-2-SQL does not implement insert using this mechanism, under any conditions.
If you need to bulk load data into SQL Server and need it to be fast, I would recommend hand coding using SqlBulkCopy.
Linq-2-SQL will attempt to perform some optimisations to speed up multiple inserts, however it still will fall short of many micro ORMs (even though no micro ORMs I know of implement SqlBulkCopy)
It will generate a single insert statement for every record, but will send them all to the server in a single batch and run in a single transaction.
That is what the SubmitChanges() outside the loop does.
If you moved it inside, then every iteration through the loop would go off to the server for the INSERT and run in it's own transaction.
I don't believe there is any way to fire off a SQL BULK INSERT.
LINQ Single Insert from List:
int i = 0;
foreach (IPAPM_SRVC_NTTN_NODE_MAP item in ipapmList)
{
++i;
if (i % 50 == 0)
{
ipdb.Dispose();
ipdb = null;
ipdb = new IPDB();
// .NET CORE
//ipdb.ChangeTracker.AutoDetectChangesEnabled = false;
ipdb.Configuration.AutoDetectChangesEnabled = false;
}
ipdb.IPAPM_SRVC_NTTN_NODE_MAP.Add(item);
ipdb.SaveChanges();
}
I would suggest you take a look at N.EntityFramework.Extension. It is a basic bulk extension framework for EF 6 that is available on Nuget and the source code is available on Github under MIT license.
Install-Package N.EntityFramework.Extensions
https://www.nuget.org/packages/N.EntityFramework.Extensions
Once you install it you can simply use BulkInsert() method directly on the DbContext instance. It support BulkDelete, BulkInsert, BulkMerge and more.
BulkInsert()
var dbcontext = new MyDbContext();
var orders = new List<Order>();
for(int i=0; i<10000; i++)
{
orders.Add(new Order { OrderDate = DateTime.UtcNow, TotalPrice = 2.99 });
}
dbcontext.BulkInsert(orders);