In trying to setup a unit test for inserting an item into an SQL Server Express (2008) database using C# Linq I've encountered an error that is causing me some trouble. The Linq code is built using Visual Studio 2008.
The exception is thrown on a system running Windows XP SP2. The Linq works fine and the record is inserted appropriately on a system running Windows 7 Home Premium (64-bit).
I've dropped and re-created the database on the XP system. I've dropped and re-created the DAL and corresponding DBML on the XP system.
Other tables with unit tests for inserts to the same database work just fine.
Inserting a record into the table using a simple insert statement in SQL Server Management Studio works appropriately.
What should I look at to find the source of the problem? What should be done to resolve the problem?
Any insight as to what the error message is really trying to say would be greatly appreciated.
Error Message
System.IndexOutOfRangeException : Index was outside the bounds of the array.
Stack Trace
at
System.Data.Linq.IdentityManager.StandardIdentityManager.MultiKeyManager`3.TryCreateKeyFromValues(Object[] values, MultiKey`2& k)
at System.Data.Linq.IdentityManager.StandardIdentityManager.IdentityCache`2.Find(Object[] keyValues)
at System.Data.Linq.IdentityManager.StandardIdentityManager.Find(MetaType type, Object[] keyValues)
at System.Data.Linq.CommonDataServices.GetCachedObject(MetaType type, Object[] keyValues)
at System.Data.Linq.ChangeProcessor.GetOtherItem(MetaAssociation assoc, Object instance)
at System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges()
at nUnit.DAL.FacilityTests.AddFacility2() in C:\SVN\SVNRevenue360\Branches\Dev\Code\ProviderAdvantage\nUnit.CoreTests\Tests\DAL\FacilityTests.cs:line 50
Insert Code
[Test]
public void AddFacility2() {
string facilityname = "Test Facility";
try {
using (PA.Database.Revenue360DB db = new PA.Database.Revenue360DB(PA.DAL.DataAccess.ConnectionString)) {
db.Log = Console.Out;
PA.Database.Facility facility = new PA.Database.Facility();
facility.id = Guid.NewGuid();
facility.Name = facilityname;
facility.Street1 = "";
facility.Street2 = "";
facility.Street3 = "";
facility.City = "";
facility.State = "";
facility.Zip = "";
facility.Description = "";
db.Facilities.InsertOnSubmit(facility);
db.SubmitChanges(); // line 50
}
} catch (Exception ex) {
Console.WriteLine(ex.GetType().FullName + ": " + ex.Message);
Console.WriteLine(ex.InnerException == null ?
"No inner exception" :
ex.InnerException.GetType().FullName + ": " + ex.InnerException.Message);
throw;
}
}
I've looked at the following SO questions without insight as to what is causing this particular issue.
https://stackoverflow.com/questions/1087172/why-am-i-getting-index-was-outside-the-bounds-of-the-array
IndexOutOfRangeException on Queryable.Single
Strange LINQ Exception (Index out of bounds)
Take a look at this link.
Here are a few excerpts:
A common cause of this error is
associations pointing in the wrong
direction. (Something that is
extremely easy to do if editing the
model by hand, partly because the
association arrow pointer is in the
opposite end of where it would appear
in an ER diagram)
and
I was having the same problem and it
was due to the fact my primary key was
two columns instead of the traditional
one. (both guids). When I added a
third column that was the sole primary
key column, it worked.
UPDATE: Did some more poking around and found this SO post. Looks like it might have something to do with your DBML...
If the code is working on one machine and not working on another the problem should be somewhere outside. Please check if the .NET Framework version on Windows XP is the same as on Windows 7. Secondly, if its XP SP2 then the Operating System might be the cause because Microsoft has changed a lot in SP3. Also check if the database has same tables. Try to reproduce the problem on the same db, i.e. take backup from Win7 and restore it on the XP (of cause backup your data first). What else? Security permissions and connection string might have an impact too.
Related
We are trying to access the DefaultFile member of an Microsoft.SqlServer.Management.Smo.Server object. After a lot of debugging, it turns out that accessing the member crashes the first time, but can then be accessed just fine. Looking at the variable in a debug window returns an exception the first time, the correct value the second and all following times.
The first access of either server.DefaultFile or server.DefaultLog throws an exception like this:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at Microsoft.SqlServer.Management.Smo.BitStorage.SetBit(Int32 itemIndex, BitIndex bitIndex, Boolean value)
at Microsoft.SqlServer.Management.Smo.PropertyCollection.SetRetrieved(Int32 index, Boolean val)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.AddObjectPropsFromDataReader(IDataReader reader, Boolean skipIfDirty, Int32 startColIdx, Int32 endColIdx)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.ImplInitialize(String[] fields, OrderBy[] orderby)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.Initialize(Boolean allProperties)
at Microsoft.SqlServer.Management.Smo.SqlSmoObject.OnPropertyMissing(String propname, Boolean useDefaultValue)
at Microsoft.SqlServer.Management.Smo.PropertyCollection.GetValueWithNullReplacement(String propertyName, Boolean throwOnNullValue, Boolean useDefaultOnMissingValue)
at Microsoft.SqlServer.Management.Smo.Server.get_DefaultFile()
at my function... etc etc
The first-access-crash is very concistent, so doing something terrible like below gets around the problem completely:
using (var sqlConnection = new SqlConnection(sourceDatabaseConnectionString.ConnectionString))
{
var svrConnection = new ServerConnection(sqlConnection);
var server = new Server(svrConnection);
// begin mega hack
try
{
// crashes on first access
var dummy = server.DefaultFile;
}
catch
{
// do absolutely nothing
}
// end mega hack
// business as usual...
var defaultFile = server.DefaultFile;
}
Of course, we don't like code like this (even if it's only in our internal tools) so any ideas of why this might be happening is welcome. Our only clue is that we've recently upgraded some instances of SQL Server 2012 to SQL Server 2014. We can sometimes get around the issue when running the code locally on a machine with SQL Server 2014 installed. The production machine that runs this code does not have an installation at all, but references DLLs. However, we can't find any differences in the versions used when debug printing the assembly versions while running the code.
I've seen similar messages when using an older version of SMO, especially when trying to use 2008R2 SMO to access 2012. Upgrading to the installs from 2008R2 Featurepack SP3 fixed my issues.
Check that there's not a more recent version of the Shared Management Objects + CLR Types + Native client driver that you could use.
I am struggling with SQL Server CE 4.0 almost all day. I get this error when I try to save new record (entity) to my database.
First a little preview - I installed SQL Server CE 4.0 via NuGet and I created a database for my project. Then I created the Entity Framework model layer and started working with that.
When I get this error my inner exception says this :
The column cannot be modified. [ Column name = Id ]
I did a little research and find out that this may be cause because of my settings for the Id property so I changed it like that :
I already have 17 records that I have inserted manually for testing purposes but I doubt this may cause any problem.
So what I try to do is this:
public override void Save()
{
using (RalBaseEntities ctx = new RalBaseEntities())
{
System.Data.Entity.DbSet<MainInfo> mainInfoEntity = ctx.Set<MainInfo>();
MainInfo entity = new MainInfo();
entity.Manager = txtManager.Text;
entity.Broker = txtBroker.Text;
mainInfoEntity.Add(entity);
ctx.SaveChanges();
}
}
So when I try to execute the Save() method I get the error above. I wrote that in previous versions one should have to create the id manually, but it's fixed in v. 4.0 and judging by the settings that I show as an image here I don't see a reason just to get a new record with an auto generated unique Id.
The word Update in DbUpdate Exception that I get is worrying me a bit. Maybe I'm trying to save the data in a wrong way but I spend a lot of time googling and it seems to be the right way.
A added a custom attribute to the Active Directory Schema. On one machine when I try to query the attribute I get errors back from my code.
Here is the C# version to test this out.
static class Program
{
static void Main()
{
Console.ReadLine();
DirectoryEntry directoryEntry = (DirectoryEntry)UserPrincipal.Current.GetUnderlyingObject();
//Execption on this line
var allowedDatabases = directoryEntry.Properties["vwDBAccess"];
foreach (var record in allowedDatabases.OfType<String>())
{
Console.WriteLine(record);
}
Console.ReadLine();
}
}
System.Runtime.InteropServices.COMException was unhandled
Message=Unknown error (0x8000500c)
Source=System.DirectoryServices
ErrorCode=-2147463156
StackTrace:
at System.DirectoryServices.PropertyValueCollection.PopulateList()
at System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry entry, String propertyName)
at System.DirectoryServices.PropertyCollection.get_Item(String propertyName)
at Sandbox_Console.Program.Main() in C:\Users\srchamberlain.VW\documents\visual studio 2010\Projects\Sandbox Console\Sandbox Console\Program.cs:line 16
InnerException:
The Error Code 0x8000500c represents E_ADS_CANT_CONVERT_DATATYPE. This only happens on one machine. I have 3 other computers (all part of the same domain as the first computer) and those behave correctly when running the exact same code for the exact same user and give the the content of the attribute. Also if I run as a different user, on the same box, but query the bad user's attributes I can pull up the information correctly when connecting as another user.
I have tried refreshing the schema on the box using the technique from this KB article but the issue is still happening.
What is going wrong on this one computer?
Clarification:
vwDBAccess is a multivalued string, so when it works directoryEntry.Properties["vwDBAccess"] return a string with there is one item, sting[] when there is more than one, and null when there are no items. This account has 3 items set. When I run as a different user and query the bad user I correctly get string[3] returned.
Typically if something is only happening on one machine in a network then it boils down to service pack and update levels of the OS or interaction with other software on the system (A/V is the worst offender).
The first thing I would do is look at the SP and updates applied to the working machines, then compare that to the non-working one. You should see one of two situations:
If the working machines are more up to date, then apply whatever updates are necessary to the non-working machine.
If the working machines are less up to date, then update one and see if it starts failing. If that's the case, you might need to contact MS.
My gut says that the non-working machine is simply out of date.
I'm currently building a registry explorer, mostly because I want to support some much better searching operations. Like 'find all' and regular expressions. One problem I'm facing is that some keys throw a security exception when opening. I HAVE TRIED running the app with administrator priviledges, my user account is an administrator also. I embedded a manifest with "requireAdministrator" requested priviledges. I have also tried setting the ClickOnce security settings to Full trust, which is incompatible with requireAdministrator, or so Visual Studio tells me.... Nothing seems to help with avoiding this exception.
I would just like to iterate over all of the keys. I do not wish to add/delete keys. If a user wishes to delete a key and does not have permission to do so, it would display an error message. I just want to be able to have unrestricted READ access. Is this possible?
FTR: I'm on Win7 x64 and using Vs2010u and project is written in C# on .net 4.0. If regedit is capable of reading all keys even if it doesn't let you edit some of them. It would seem appropriate that we too can make an app to do the same thing. Though I'm finding it very difficult, and there doesn't seem to be any real help on the www. Only link-link circles, yay.
[EDIT]
Here's the code that reads the keys:
private void IterateSubKeys(RegistryKeyModel key) {
var subKeys = key.Key.GetSubKeyNames();
var values = key.Key.GetValueNames();
foreach (var valuename in values) {
try {
var valueKind = key.Key.GetValueKind(valuename);
var value = key.Key.GetValue(valuename);
key.Values.Add(new RegistryValueModel(valuename, value, valueKind));
}
catch { }
}
foreach (var keyname in subKeys) {
try {
var subkey = key.Key.OpenSubKey(
keyname,
RegistryKeyPermissionCheck.ReadSubTree,
RegistryRights.ReadKey);
key.SubKeys.Add(new RegistryKeyModel(subkey));
}
catch { Console.WriteLine("Error reading key: {0}", keyname); }
}
}
This is by design. There are lots of security related keys that can only accessible to the System account. You can't use that account. Regedit can't read these keys either, they are just not visible. Avoiding the expensive exception is going to require pinvoke.
I have a OdbcDataReader that gets data from a database and returns a set of records.
The code that executes the query looks as follows:
OdbcDataReader reader = command.ExecuteReader();
while (reader.Read())
{
yield return reader.AsMovexProduct();
}
The method returns an IEnumerable of a custom type (MovexProduct). The convertion from an IDataRecord to my custom type MovexProduct happens in an extension-method that looks like this (abbrev.):
public static MovexProduct AsMovexProduct(this IDataRecord record)
{
var movexProduct = new MovexProduct
{
ItemNumber = record.GetString(0).Trim(),
Name = record.GetString(1).Trim(),
Category = record.GetString(2).Trim(),
ItemType = record.GetString(3).Trim()
};
if (!record.IsDBNull(4))
movexProduct.Status1 = int.Parse(record.GetString(4).Trim());
// Additional properties with IsDBNull checks follow here.
return movexProduct;
}
As soon as I hit the if (!record.IsDBNull(4)) I get an OverflowException with the exception message "Arithmetic operation resulted in an overflow."
StackTrace:
System.OverflowException was unhandled by user code
Message=Arithmetic operation resulted in an overflow.
Source=System.Data
StackTrace:
at System.Data.Odbc.OdbcDataReader.GetSqlType(Int32 i)
at System.Data.Odbc.OdbcDataReader.GetValue(Int32 i)
at System.Data.Odbc.OdbcDataReader.IsDBNull(Int32 i)
at JulaAil.DataService.Movex.Data.ExtensionMethods.AsMovexProduct(IDataRecord record) [...]
I've never encountered this problem before and I cannot figure out why I get it. I have verified that the record exists and that it contains data and that the indexes I provide are correct. I should also mention that I get the same exception if I change the if-statemnt to this: if (record.GetString(4) != null). What does work is encapsulating the property-assignment in a try {} catch (NullReferenceException) {} block - but that can lead to performance-loss (can it not?).
I am running the x64 version of Visual Studio and I'm using a 64-bit odbc driver.
Has anyone else come across this? Any suggestions as to how I could solve / get around this issue?
Many thanks!
For any one experiencing the same issue, the way I solved this was to switch from the Odbc* classes to their OleDb* counterparts. This of course demands that your data driver has support for OleDb connections.
Which DB are you trying to talk to? If it uses some "private" column types that can cause problems. That doesn't apply to SQL Server of course :-)
Also check that you are compiling and running as x64 (Process Explorer will show you thsi and even plain tack manager shows it). devenv.exe will still be x86 but your actual binary should run as x64. The reason I mention is that crossing 32/64 bit boundary is notorious for breaking 3rd party ODBC drivers.