Update
I think the issue may be that I have my associations set up wrong....some tables are one to one and I have them as one to many...
Im writing a reports program using ironpython C# and linq2sql. The error occurs in the report python file at this code:
#Evaluation Comment Workflow Records
doc.EvaluationCommentworkflowRecords = [];
if (doc.crRecord.V_SOS_CR_EVAL and doc.crRecord.V_SOS_CR_EVAL.V_SOS_WFDSTs.Count > 0):
doc.EvaluationCommentworkflowRecords = doc.crRecord.V_SOS_CR_EVAL.V_SOS_WFDSTs.Where(lambda p: p.DOCTYPE and
p.DOCTYPE == (doc.evalDocType) and
p.ST_DATE).OrderBy(lambda p: p.ST_DATE).ToList()
#End Evaluation Comment Workflow Records
return doc
The error message I get says EntitySet[V_SOS_CR_EVAL] object has no attribute V_SOS_WFDSTs.
But i make the connection in linq2sql with an association and in the dataprovider class:
//evaluation and subs
loadOptions.LoadWith<V_SOS_CR>(p => p.V_SOS_CR_EVAL);
loadOptions.LoadWith<V_SOS_CR_EVAL>(p => p.SOS_ATTs);
loadOptions.LoadWith<V_SOS_CR_EVAL>(p => p.V_SOS_WFDSTs);
and this is the DBML designer.cs file below:
public V_SOS_CR_EVAL()
{
this._SOS_ATTs = new EntitySet<SOS_ATT>(new Action<SOS_ATT>(this.attach_SOS_ATTs), new Action<SOS_ATT>(this.detach_SOS_ATTs));
this._V_SOS_WFDSTs = new EntitySet<V_SOS_WFDST>(new Action<V_SOS_WFDST>(this.attach_V_SOS_WFDSTs), new Action<V_SOS_WFDST>(this.detach_V_SOS_WFDSTs));
this._V_SOS_CR = default(EntityRef<V_SOS_CR>);
OnCreated();
}
then farther down in the code it has:
public V_SOS_WFDST()
{
this._V_SOS_CR = default(EntityRef<V_SOS_CR>);
this._V_SOS_CR_MRULE = default(EntityRef<V_SOS_CR_MRULE>);
this._V_SOS_CR_OPERABILITY = default(EntityRef<V_SOS_CR_OPERABILITY>);
this._V_SOS_CR_REPORTABILITY = default(EntityRef<V_SOS_CR_REPORTABILITY>);
this._V_SOS_CR_EVAL = default(EntityRef<V_SOS_CR_EVAL>);
this._V_SOS_CR_ACTION = default(EntityRef<V_SOS_CR_ACTION>);
OnCreated();
}
If anyone can think of how to fix this error please let me know!
Thanks,
Nick
The problem was in the Associations with the tables. I had many set to one to many when they should have been one to one...
Related
I am trying to add an entry into a table and use the primary key of that added entry to create an additional entry into another table.
The error I am getting is
The transaction manager has disabled its support for remote/network
transactions. (Exception from HRESULT: 0x8004D024)
I believe this is caused by creating multiple connections within a single TransactionScope, but I am doing everything within one context / using statement, so I do not believe that I should be receiving this error.
Service
[OperationBehavior(TransactionScopeRequired = true)]
public void CreateGroup(NewGroupData data)
{
var groupRepo = _GroupRepo ?? new InvestigatorGroupRepository();
groupRepo.CreateGroup(data.UserId, data.InvestigatorGroupName, data.HasGameAssignment, data.InstitutionId);
}
Repository
public void CreateGroup(string userId, string investigatorGroupName, bool hasGameAssignment, int institutionId)
{
using (var context = new GameDbContext())
{
var newGroup = new InvestigatorGroup()
{
InvestigatorGroupName = investigatorGroupName,
HasGameAssignment = hasGameAssignment,
InstitutionId = institutionId,
IsTrashed = false
};
int institutionUserId =
context.InstitutionUsers.Where(
iu => !iu.IsTrashed && iu.APUser.UserId == userId && iu.InstitutionId == institutionId).Select(iu => iu.InstitutionUserId).Single();
var newGroupUser = new InvestigatorGroupUser()
{
InstitutionUserId = institutionUserId,
InvestigatorGroup = newGroup,
CreationDate = DateTime.Now
};
context.InvestigatorGroupUsers.Add(newGroupUser);
context.SaveChanges();
}
}
You start with a wrong assumption.
The line...
int newGroupId = context.InvestigatorGroups.Add(newGroup).InvestigatorGroupId;
...will always assign 0 to newGroupId. The Add method only marks the entity for insert, but doesn't actually insert it. Only SaveChanges writes data to the database, not any other method in Entity Framework.
So the assignment...
InvestigatorGroupId = newGroupId,
...is faulty as well. You have to assign the new InvestigatorGroup to a navigation property in InvestigatorGroupUser:
InvestigatorGroup = newGroup,
Add this navigation property to InvestigatorGroupUser if you haven't got it yet.
If you have that, it's enough to execute these lines:
context.InvestigatorGroupUsers.Add(newGroupUser);
context.SaveChanges();
No need to Add the newGroup object too, It will be added by adding newGroupUser.
So if you do that, the only transaction you need is the one that SaveChanges uses internally by default. For the code you show, you don't need a TransactionScope. If this is part of a greater WCF transaction the story may be different, but I think at least you needed some misconceptions to be straightened out.
As the title says, I have a problem writing to local database. I generated a edmx Model from this, and I can easily read from it.
EDMXNS.TOWDataBasev1Entities db = new EDMXNS.TOWDataBasev1Entities();
var query = from p in db.Accounts select p;
foreach (EDMXNS.Accounts s in query)
Console.WriteLine(s.AccountName);
That works fine. However when I try to write to the database, nothing happens. I do not get any errors, exceptions etc. I figure, since I can read from the database, that it's not a connection problem.
Here is the code i have for writing.
EDMXNS.TOWDataBasev1Entities db = new EDMXNS.TOWDataBasev1Entities();
EDMXNS.Accounts acc = new EDMXNS.Accounts();
acc.AccountID = 1;
acc.AccountName = "testuser";
acc.AccountPW = "testpw";
acc.PersonDataID = 0;
db.AddToAccounts(acc);
db.SaveChanges();
It is worthwhile to meantion that my Accounts.AccountID has identity/autoincrement, but I have tried both setting it to the next known value, or simply not setting it at all.
Do anyone have an idea as to what might cause this problem?
EDIT: I also tried to remove the custom name space, delete all records of the database and reimport it all.
Removing the custom tool name space, results in errors like these:
Ambiguity between 'TOWServer.Accounts.AccountName' and 'TOWServer.Accounts.AccountName'
Which doesnt tell me anything.
Reimporting everything now gives me an exception:
"Unable to load the specified metadata resource"
I've always use this format when adding records with EF, Try following this format:
using (MovieStoreEntities context = new MoveStoreEntities())
{
try
{
context.Movies.AddObject(new Movie() { MovieID = 234,
Title = "Sleepless Nights in Seattle", Quantity = 10 });
context.SaveChanges();
}
catch(Exception ex)
{
Console.WriteLine(ex.InnerException.Message);
}
}
I am currently trying to create a new order (which will be shown below) in a web service, and then send that data to insert a new row into the database. For some reason my DBML / Data Context does not allow me to use InsertOnSubmit.
Any ideas? I haven't used Linq to Sql in about 7 months.
Thanks in advance.
[WebMethod]
public string InsertOrderToDatabases()
{
//Start Data Contexts ------
DataContext db = new DataContext(System.Configuration.ConfigurationManager.AppSettings["RainbowCMSConnectionString"]);
DataContext dcSqlOES = new DataContext(System.Configuration.ConfigurationManager.AppSettings["OESConnectionString"]);
//Get table from local database
Table<Schedule> Schedule = db.GetTable<Schedule>();
//Find last order number in databases
var lastOrderNumber = from lOrder in Schedule
orderby lOrder.templ_idn descending
select lOrder.templ_idn;
int firstOrderID;
var firstOrder = lastOrderNumber.FirstOrDefault();
firstOrderID = firstOrder.Value + 1;
qrOrder qrOrd = new qrOrder
{
.... data in here creating a new order
};
//TODO: fix below with an insert on submit
if (qrOrd != null)
{
// **Schedule.InsertOnSubmit(qrOrd);**
}
//db.GetTable<Schedule>().InsertOnSubmit(qrOrd);
try
{
//Submit the changes to the database
db.SubmitChanges();
return "Orders were sent to the databases.";
}
catch ()
{
}
}
Based on your response, it appears that you are using the wrong table, or perhaps the wrong data type. I also noticed that when you declare your localSchedule variable, you declare it as type Table<Schedule>, which means it should contain Schedule entities, not qrOrder entities.
Table<TEntity>.InsertOnSubmit expects a specific strongly typed entity to be passed in. In your case, it is expecting Web_Service.Schedul‌e, but you are trying to pass in a qrOrder.
Schedule.InsertOnSubmit(qrOrd);
That line will not treat to submit changes to connected entity , Try this
db.Schedule.InsertOnSubmit(qrOrd);
db.SubmitChanges();
you can try with
db.GetTable(typeof(Schedule)).InsertOnSubmit(qrOrd);
Or
db.GetTable(qrOrd.GetType()).InsertOnSubmit(qrOrd);
I'm new to Entify Framework so this is probably a very basic question. In a WinForms application I have a data entry page that works fine until I add a listbox and try to update the database with the selections that have been made.
On the form the user selects a file to upload and specifies one or more departments that can access the file. Here's how I thought it would work:
using (var ctx = new FCEntities())
{
var batch = new Batch() { Description = txtDescription.Text, Filename = filename, Departments = (System.Data.Objects.DataClasses.EntityCollection<Department>)lstDepartments.SelectedItems };
ctx.AddToBatches(batch);
ctx.SaveChanges();
}
But when this didn't work I did some research and learned that I can't cast the SelectedItems to EntityCollection so I decided to copy the items from the original collection into a new collection and then use the new collection as follows:
using (var ctx = new FCEntities())
{
var departments = new System.Data.Objects.DataClasses.EntityCollection<Department>();
foreach (var department in lstDepartments.SelectedItems)
{
departments.Add((Department)department);
}
var batch = new Batch() {Description = txtDescription.Text, Filename = filename, Departments=departments };
ctx.AddToBatches(batch);
ctx.SaveChanges();
}
This didn't work either and gave this error on the departments.Add line:
"An object that is attached to an ObjectContext cannot be added to an
EntityCollection or EntityReference that is not associated with a
source object."
I don't understand because it doesn't appear to me that the department object is attached to the ObjectContext? I'm obviously missing something fundamental, so any advice and/or links to examples of how others do this would be appreciated.
I wanted to leave an answer to this in case someone else runs into this someday. The comments left by Wiktor were helpful in getting me in the right direction. I decided I had a lack of fundamental understanding so I did some reading on MSDN and was able to resolve my issue.
The datamodel behind this existed of three tables: Batches, Departments, and Batches_Departments which allowed for a many to many relationship between Batches and Departments.
The problem with my original code/logic, in a nutshell, was that the Department objects in the ListBox were associated with a different context than the one I was using in my Save method. EF didn't like this for obvious reasons (at least now they are obvious), so in the save method I used the ID from the selected Departments to get a reference to the same Department in the current context. I could then add this Department to the newly created batch.
Here's what the code now looks like:
using (var ctx = new FCEntities())
{
var batch = new Batch() { Description = txtDescription.Text, Filename = filename};
foreach (var department in lstDepartments.CheckedItems)
{
var dept = (from d in ctx.Departments where d.DepartmentID == ((Department)department).DepartmentID select d).First();
batch.Departments.Add(dept);
}
ctx.Batches.AddObject(batch);
ctx.SaveChanges();
}
Hopefully this helps someone else who is dealing with the same issue.
I am writing a small application that does a lot of feed processing. I want to use LINQ EF for this as speed is not an issue, it is a single user app and, in the end, will only be used once a month.
My questions revolves around the best way to do bulk inserts using LINQ EF.
After parsing the incoming data stream I end up with a List of values. Since the end user may end up trying to import some duplicate data I would like to "clean" the data during insert rather than reading all the records, doing a for loop, rejecting records, then finally importing the remainder.
This is what I am currently doing:
DateTime minDate = dataTransferObject.Min(c => c.DoorOpen);
DateTime maxDate = dataTransferObject.Max(c => c.DoorOpen);
using (LabUseEntities myEntities = new LabUseEntities())
{
var recCheck = myEntities.ImportDoorAccess.Where(a => a.DoorOpen >= minDate && a.DoorOpen <= maxDate).ToList();
if (recCheck.Count > 0)
{
foreach (ImportDoorAccess ida in recCheck)
{
DoorAudit da = dataTransferObject.Where(a => a.DoorOpen == ida.DoorOpen && a.CardNumber == ida.CardNumber).First();
if (da != null)
da.DoInsert = false;
}
}
ImportDoorAccess newIDA;
foreach (DoorAudit newDoorAudit in dataTransferObject)
{
if (newDoorAudit.DoInsert)
{
newIDA = new ImportDoorAccess
{
CardNumber = newDoorAudit.CardNumber,
Door = newDoorAudit.Door,
DoorOpen = newDoorAudit.DoorOpen,
Imported = newDoorAudit.Imported,
RawData = newDoorAudit.RawData,
UserName = newDoorAudit.UserName
};
myEntities.AddToImportDoorAccess(newIDA);
}
}
myEntities.SaveChanges();
}
I am also getting this error:
System.Data.UpdateException was unhandled
Message="Unable to update the EntitySet 'ImportDoorAccess' because it has a DefiningQuery and no element exists in the element to support the current operation."
Source="System.Data.SqlServerCe.Entity"
What am I doing wrong?
Any pointers are welcome.
You can do multiple inserts this way.
I've seen the exception you're getting in cases where the model (EDMX) is not set up correctly. You either don't have a primary key (EntityKey in EF terms) on that table, or the designer has tried to guess what the EntityKey should be. In the latter case, you'll see two or more properties in the EDM Designer with keys next to them.
Make sure the ImportDoorAccess table has a single primary key and refresh the model.