Quantcast
Channel: Entity Framework
Viewing all 10318 articles
Browse latest View live

Edited Unassigned: Make EF load data from database, not cache [2588]

$
0
0
I have asked this question [here](https://entityframework.codeplex.com/discussions/569592), but got no response.
So, here's the problem. I have lots of tables and lots of columns in them. As I said in that post, when I need fresh data from database, EF takes data not from database, but from local cache. In [similar post](https://entityframework.codeplex.com/discussions/569761) it was insisted to use fresh context every time I need fresh data. So, it means that every time EF will initialize quadrillions of tables and columns? This is not an option, really. Please, add some "LoadDataFromDatabase" method to clear local cache and populate it with fresh data.
Also, disposing context after binding retrieved data to DataGrid doesn't let edit data in it and persist because, well, the context has been disposed! The actual error "System.InvalidOperationException: The operation cannot be completed because the DbContext has been disposed".

Edited Unassigned: Make EF load data from database, not cache [2588]

$
0
0
I have asked this question [here](https://entityframework.codeplex.com/discussions/569592), but got no response.
So, here's the problem. I have lots of tables and lots of columns in them. The program is used by many users, so that each of them must see the changes of each other. As I said in that post, when I need fresh data from database, EF takes data not from database, but from local cache. In [similar post](https://entityframework.codeplex.com/discussions/569761) it was insisted to use fresh context every time I need fresh data. So, it means that every time EF will initialize quadrillions of tables and columns? This is not an option, really. Please, add some "LoadDataFromDatabase" method to clear local cache and populate it with fresh data.
Also, disposing context after binding retrieved data to DataGrid doesn't let edit data in it and persist because, well, the context has been disposed! The actual error "System.InvalidOperationException: The operation cannot be completed because the DbContext has been disposed".

Commented Unassigned: Linq.Any() throw NullReferenceException [2587]

$
0
0
I couldn't understand what was happening when I use Linq.Any() method to check if EF object contains a specific value, the code throws a NullReferenceException on variable with data prior it's use.

The code below:


public ML.Order FetchOrder(ML.MLDBContext db, long OrderID)
{
if (db == null)
db = new ML.MLDBContext();

//avoided code to fetch the Order details from another system via API

Order apiOrder = api.OrdersGet(OrderID);

//avoided code to test null results

bool isNew = false; //to check if fetched order is new or must be updated on DB

//load from DB
ML.Order dbOrder = db.Orders.Where(o => o.OrderID == apiOrder.id).FirstOrDefault();
if (dbOrder == null)
{
isNew = true;

//avoided code to fill dbOrder with apiOrder data

//Below code check if user bought the same product before

//the error is thrown here but it's not null
string ListingID = apiOrder.order_items.First().item.id;
var previousOrders = db.Orders.Where(order => order.OrderID != apiOrder.id && order.CustomerID == apiOrder.buyer.id && order.SellerID == apiOrder.seller.id).ToList();

foreach (ML.Order prevOrder in previousOrders)
{
if (prevOrder.OrderedItems.Any(i => i.ListingID == ListingID)) //Line who causes the error
{
//code to mask as reordered item
}
}

Some points:

I'm sure "apiOrder.order_items.First().item.id" always have any value.

I'm sure the Order contains the item I'm looking for and the field isn't nullable.

When I comment the line who causes the error, the debug will pass through without errors


To solve this problem, I had to replace **Link.Any()** by **foreach**

foreach (ML.Order prevOrder in previousOrders)
{
foreach (ML.OrderedItem item in prevOrder.OrderedItems)
{
if (item.ListingID == ListingID)
{
//code to mask as reordered item
}
}

}


My doubt is:
Does Linq.Any() or EntityFramework Monitor variables prior to it's declaration and use?

Why the NullreferenceException was trowed on variable prior it usage?

What's the problem using the Linq.Any() method to check the existence of a value inside EF object?

Comments: Without the stack trace, I can only guess... Is prevOrder.OrderItems null? Any and all standard LINQ operators check for null (and throw) on the collection they are applied to.

Commented Unassigned: Not optimal query using GroupBy and Average [2584]

$
0
0
On Entity Framework 6.1.1, given this expression:

db.GEN_PARTEOEEPERDIDAS
.Where(p => (!p.MK_BAJA.HasValue || (p.MK_BAJA.HasValue && p.MK_BAJA.Value != 1))
&& p.GEN_PARTEOEE.MK_VALIDADO.HasValue && p.GEN_PARTEOEE.MK_VALIDADO.Value == 1
&& p.GEN_PARTEOEE.FECHAPARTE.Value >= fechaInicio
&& p.GEN_PARTEOEE.FECHAPARTE < SqlFunctions.DateAdd("DAY", 1, fechaFin))
.GroupBy(g => new { ID = g.GEN_PERDIDAS.ID, Descripcion = g.GEN_PERDIDAS.DESCRIPCION })
.Select(g => new Item()
{
Categoria = g.Key.Descripcion,
Serie1Valor = g.Average(p => p.DURACION) ?? 0
})
.OrderByDescending(g => g.Serie1Valor)
.ToList();

I'm getting this SQL:

SELECT
[Project1].[C1] AS [C1],
[Project1].[DESCRIPCION] AS [DESCRIPCION],
[Project1].[C2] AS [C2]
FROM ( SELECT
[GroupBy1].[K2] AS [DESCRIPCION],
1 AS [C1],
CASE WHEN ([GroupBy1].[A1] IS NULL) THEN cast(0 as decimal(18)) ELSE [GroupBy1].[A2] END AS [C2]
FROM ( SELECT
[Filter1].[IDPERDIDA] AS [K1],
[Filter1].[DESCRIPCION] AS [K2],
AVG([Filter1].[DURACION]) AS [A1],
AVG([Filter1].[DURACION]) AS [A2]
FROM ( SELECT [Extent1].[IDPERDIDA] AS [IDPERDIDA], [Extent1].[DURACION] AS [DURACION], [Extent2].[FECHAPARTE] AS [FECHAPARTE], [Extent3].[DESCRIPCION] AS [DESCRIPCION]
FROM [dbo].[GEN_PARTEOEEPERDIDAS] AS [Extent1]
INNER JOIN [dbo].[GEN_PARTEOEE] AS [Extent2] ON [Extent1].[IDPARTEOEE] = [Extent2].[ID]
LEFT OUTER JOIN [dbo].[GEN_PERDIDAS] AS [Extent3] ON [Extent1].[IDPERDIDA] = [Extent3].[ID]
WHERE (([Extent1].[MK_BAJA] IS NULL) OR (([Extent1].[MK_BAJA] IS NOT NULL) AND ( NOT ((1 = [Extent1].[MK_BAJA]) AND ([Extent1].[MK_BAJA] IS NOT NULL))))) AND ([Extent2].[MK_VALIDADO] IS NOT NULL) AND (1 = [Extent2].[MK_VALIDADO])
) AS [Filter1]
WHERE ([Filter1].[FECHAPARTE] >= '01/04/2014 0:00:00') AND ([Filter1].[FECHAPARTE] < (DATEADD(DAY, cast(1 as float(53)), '18/11/2014 0:00:00')))
GROUP BY [Filter1].[IDPERDIDA], [Filter1].[DESCRIPCION]
) AS [GroupBy1]
) AS [Project1]
ORDER BY [Project1].[C2] DESC

The strange components of the query are:
- Double average calculation
AVG([Filter1].[DURACION]) AS [A1],
AVG([Filter1].[DURACION]) AS [A2]
- Weird case instruction
CASE WHEN ([GroupBy1].[A1] IS NULL) THEN cast(0 as decimal(18)) ELSE [GroupBy1].[A2] END AS [C2]

I was expecting just an AVG expression, not twice.

Is there an explanation for this behaviour that I'm missing?
Comments: This seems to be a bug/limitation that was inherited from EF5. "g.Average(p => p.DURACION) ?? 0" is translated into a CASE statement like "CASE expression IS NULL THEN 0 ELSE expression" where expression is "g.Average(p => p.DURACION)". This results in the double average calculation because expression appears twice in the CASE statement and EF does not seem to be able to simplify it. One workaround that could work is to replace: .Select(g => new Item() { Categoria = g.Key.Descripcion, Serie1Valor = g.Average(p => p.DURACION) ?? 0 }) with .Select( g => new { Categoria = g.Key.Descripcion, Serie1Valor = g.Average(p => p.DURACION) }) .Select( x => new Item { Categoria = x.Categoria, Serie1Valor = x.Serie1Valor ?? 0 })

Commented Issue: UpForGrabs: Ignore properties of inheritance hierarchies via convention [2243]

$
0
0
When ignoring properties in an inheritance hierarchy via a convention rather than the NotMapped attribute, an InvalidOperationException is thrown. The reason is in method LiftInheritedProperties of TypeMapper:

if (!this._mappingContext.AttributeProvider.GetAttributes(property).OfType<NotMappedAttribute>().Any<NotMappedAttribute>())

is hard-coded to NotMapped attributes, i.e. ignores by convention are not considered in this method.

Comments: I believe this is an example of this problem, although this is to me a configuration error, not a convention error. public class A { public int Id { get; set; } [NotMapped] public B bClass { get; set; } } public class B { public int Id { get; set; } } public class APrime : A { } public class A_Mapping : EntityTypeConfiguration<A> { public A_Mapping() { HasKey(t => t.Id); Ignore(t => t.bClass); } } public class APrime_Mapping : EntityTypeConfiguration<APrime> { public APrime_Mapping() { HasKey (t => t.Id); Ignore(t => t.bClass); } } public class MyContext : DbContext { public MyContext() : base("HierarchyMappingErrorConnectionString") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); } } public class MyContext : DbContext { public MyContext() : base("HierarchyMappingErrorConnectionString") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly()); } } [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { using (var ctxt = new MyContext()) { var x = (from t in ctxt.Set<A>().AsQueryable() select t); } } } If the NotMappedAttribute is removed from the bClass property in class A, the InvalidOperationException is thrown when the context is built.

New Comment on "Interception"

$
0
0
Does IDbCommandInterceptor remain in EF7?

Created Unassigned: Custom Convention ignore replacement of the DbUpdateCommandTree [2589]

$
0
0
I'm writing custom convention which replace the DbUpdateCommandTree
it's change both the set clauses and the returning.

unfortunately the ExecuteAsync (DynamicUpdateCommand) ignore the new DbUpdateCommandTree returning
and check if (_modificationCommandTree.HasReader) against the original tree.
this is why the modified returning value doesn't mapped back to the entities

Commented Unassigned: Not optimal query using GroupBy and Average [2584]

$
0
0
On Entity Framework 6.1.1, given this expression:

db.GEN_PARTEOEEPERDIDAS
.Where(p => (!p.MK_BAJA.HasValue || (p.MK_BAJA.HasValue && p.MK_BAJA.Value != 1))
&& p.GEN_PARTEOEE.MK_VALIDADO.HasValue && p.GEN_PARTEOEE.MK_VALIDADO.Value == 1
&& p.GEN_PARTEOEE.FECHAPARTE.Value >= fechaInicio
&& p.GEN_PARTEOEE.FECHAPARTE < SqlFunctions.DateAdd("DAY", 1, fechaFin))
.GroupBy(g => new { ID = g.GEN_PERDIDAS.ID, Descripcion = g.GEN_PERDIDAS.DESCRIPCION })
.Select(g => new Item()
{
Categoria = g.Key.Descripcion,
Serie1Valor = g.Average(p => p.DURACION) ?? 0
})
.OrderByDescending(g => g.Serie1Valor)
.ToList();

I'm getting this SQL:

SELECT
[Project1].[C1] AS [C1],
[Project1].[DESCRIPCION] AS [DESCRIPCION],
[Project1].[C2] AS [C2]
FROM ( SELECT
[GroupBy1].[K2] AS [DESCRIPCION],
1 AS [C1],
CASE WHEN ([GroupBy1].[A1] IS NULL) THEN cast(0 as decimal(18)) ELSE [GroupBy1].[A2] END AS [C2]
FROM ( SELECT
[Filter1].[IDPERDIDA] AS [K1],
[Filter1].[DESCRIPCION] AS [K2],
AVG([Filter1].[DURACION]) AS [A1],
AVG([Filter1].[DURACION]) AS [A2]
FROM ( SELECT [Extent1].[IDPERDIDA] AS [IDPERDIDA], [Extent1].[DURACION] AS [DURACION], [Extent2].[FECHAPARTE] AS [FECHAPARTE], [Extent3].[DESCRIPCION] AS [DESCRIPCION]
FROM [dbo].[GEN_PARTEOEEPERDIDAS] AS [Extent1]
INNER JOIN [dbo].[GEN_PARTEOEE] AS [Extent2] ON [Extent1].[IDPARTEOEE] = [Extent2].[ID]
LEFT OUTER JOIN [dbo].[GEN_PERDIDAS] AS [Extent3] ON [Extent1].[IDPERDIDA] = [Extent3].[ID]
WHERE (([Extent1].[MK_BAJA] IS NULL) OR (([Extent1].[MK_BAJA] IS NOT NULL) AND ( NOT ((1 = [Extent1].[MK_BAJA]) AND ([Extent1].[MK_BAJA] IS NOT NULL))))) AND ([Extent2].[MK_VALIDADO] IS NOT NULL) AND (1 = [Extent2].[MK_VALIDADO])
) AS [Filter1]
WHERE ([Filter1].[FECHAPARTE] >= '01/04/2014 0:00:00') AND ([Filter1].[FECHAPARTE] < (DATEADD(DAY, cast(1 as float(53)), '18/11/2014 0:00:00')))
GROUP BY [Filter1].[IDPERDIDA], [Filter1].[DESCRIPCION]
) AS [GroupBy1]
) AS [Project1]
ORDER BY [Project1].[C2] DESC

The strange components of the query are:
- Double average calculation
AVG([Filter1].[DURACION]) AS [A1],
AVG([Filter1].[DURACION]) AS [A2]
- Weird case instruction
CASE WHEN ([GroupBy1].[A1] IS NULL) THEN cast(0 as decimal(18)) ELSE [GroupBy1].[A2] END AS [C2]

I was expecting just an AVG expression, not twice.

Is there an explanation for this behaviour that I'm missing?
Comments: This seems to be a bug/limitation that was inherited from EF5. "g.Average(p => p.DURACION) ?? 0" is translated into a CASE statement like "CASE expression IS NULL THEN 0 ELSE expression" where expression is "g.Average(p => p.DURACION)". This results in the double average calculation because expression appears twice in the CASE statement and EF does not seem to be able to simplify it. One workaround that could work is to replace: ``` .Select(g => new Item() { Categoria = g.Key.Descripcion, Serie1Valor = g.Average(p => p.DURACION) ?? 0 }) ``` with ``` .Select(g => new { Categoria = g.Key.Descripcion, Serie1Valor = g.Average(p => p.DURACION) }) .Select(x => new Item { Categoria = x.Categoria, Serie1Valor = x.Serie1Valor ?? 0 }) ```

Edited Unassigned: Custom Convention ignore replacement of the DbUpdateCommandTree [2589]

$
0
0
I'm writing custom convention which replace the DbUpdateCommandTree
it's change both the set clauses and the returning.

unfortunately the ExecuteAsync (DynamicUpdateCommand) ignore the new DbUpdateCommandTree returning
and check if (_modificationCommandTree.HasReader) against the original tree.
this is why the modified returning value doesn't mapped back to the entities

Edited Unassigned: Custom Convention ignore replacement of the DbUpdateCommandTree [2589]

$
0
0
I'm writing custom convention which replace the DbUpdateCommandTree
it's change both the set clauses and the returning.

unfortunately the ExecuteAsync (DynamicUpdateCommand) ignore the new DbUpdateCommandTree returning
and check if (_modificationCommandTree.HasReader) against the original tree.
this is why the modified returning value doesn't mapped back to the entities

Edited Feature: UpForGrabs: Add the SQL Format function to Entity Framework [2586]

$
0
0
Add the SQL 2012+ FORMAT function to System.Data.Entity.SqlServer.SqlFunctions
http://msdn.microsoft.com/en-us/library/hh213505(v=sql.110).aspx

Created Issue: Investigate impact of DBCC TRACEON [2590]

$
0
0
According to [this article](http://spaghettidba.com/2013/02/08/using-querytraceon-in-plan-guides/), there might be a potential permissions issue when a low-privileges account executes a query that uses a QUERYTRACEON option. For example:
```SQL
SELECT *
FROM [AdventureWorks2012].[Person].[Person]
OPTION (QUERYTRACEON 4199)
```
If the user doesn't have enough privileges then the following error will return from the server:
```
Msg 2571, Level 14, State 3, Line 1
User ‘guest’ does not have permission to run DBCC TRACEON.
```
This is worthy of investigation since [changeset 6f4a59148c5c](http://entityframework.codeplex.com/SourceControl/changeset/6f4a59148c5c980d42d61bcc594a2837a236ef6f) tried to fix workitem #2445 by adding a QUERYTRACEON option to the process of discovering the store schema as a workaround given that SQL Server 2014 has a performance regression and this trace flag tells the engine to behave as SQL Server 2012 would for this query.

If this change affects users with low privileges negatively (meaning, they used to be able to obtain the store schema information but now can't) then we must address it as a compatibility issue.

Edited Issue: Investigate impact of DBCC TRACEON [2590]

$
0
0
According to [this article](http://spaghettidba.com/2013/02/08/using-querytraceon-in-plan-guides/), there might be a potential permissions issue when a low-privileges account executes a query that uses a QUERYTRACEON option. For example:
```SQL
SELECT *
FROM [AdventureWorks2012].[Person].[Person]
OPTION (QUERYTRACEON 4199)
```
If the user doesn't have enough privileges then the following error will return from the server:
```
Msg 2571, Level 14, State 3, Line 1
User ‘guest’ does not have permission to run DBCC TRACEON.
```
This is worthy of investigation since [changeset 6f4a59148c5c](http://entityframework.codeplex.com/SourceControl/changeset/6f4a59148c5c980d42d61bcc594a2837a236ef6f) tried to fix workitem [2445](https://entityframework.codeplex.com/workitem/2445) by adding a QUERYTRACEON option to the process of discovering the store schema as a workaround given that SQL Server 2014 has a performance regression and this trace flag tells the engine to behave as SQL Server 2012 would for this query.

If this change affects users with low privileges negatively (meaning, they used to be able to obtain the store schema information but now can't) then we must address it as a compatibility issue.

Commented Unassigned: Linq.Any() throw NullReferenceException [2587]

$
0
0
I couldn't understand what was happening when I use Linq.Any() method to check if EF object contains a specific value, the code throws a NullReferenceException on variable with data prior it's use.

The code below:


public ML.Order FetchOrder(ML.MLDBContext db, long OrderID)
{
if (db == null)
db = new ML.MLDBContext();

//avoided code to fetch the Order details from another system via API

Order apiOrder = api.OrdersGet(OrderID);

//avoided code to test null results

bool isNew = false; //to check if fetched order is new or must be updated on DB

//load from DB
ML.Order dbOrder = db.Orders.Where(o => o.OrderID == apiOrder.id).FirstOrDefault();
if (dbOrder == null)
{
isNew = true;

//avoided code to fill dbOrder with apiOrder data

//Below code check if user bought the same product before

//the error is thrown here but it's not null
string ListingID = apiOrder.order_items.First().item.id;
var previousOrders = db.Orders.Where(order => order.OrderID != apiOrder.id && order.CustomerID == apiOrder.buyer.id && order.SellerID == apiOrder.seller.id).ToList();

foreach (ML.Order prevOrder in previousOrders)
{
if (prevOrder.OrderedItems.Any(i => i.ListingID == ListingID)) //Line who causes the error
{
//code to mask as reordered item
}
}

Some points:

I'm sure "apiOrder.order_items.First().item.id" always have any value.

I'm sure the Order contains the item I'm looking for and the field isn't nullable.

When I comment the line who causes the error, the debug will pass through without errors


To solve this problem, I had to replace **Link.Any()** by **foreach**

foreach (ML.Order prevOrder in previousOrders)
{
foreach (ML.OrderedItem item in prevOrder.OrderedItems)
{
if (item.ListingID == ListingID)
{
//code to mask as reordered item
}
}

}


My doubt is:
Does Linq.Any() or EntityFramework Monitor variables prior to it's declaration and use?

Why the NullreferenceException was trowed on variable prior it usage?

What's the problem using the Linq.Any() method to check the existence of a value inside EF object?

Comments: Sorry, but I can't take a stacktrace now. I'll try to take soon. you need more info or stacktrace is enough? I debugged everything many times, every variable was filled, nothing null. The problem was solved when I removed the linq query. Another point: I had to add a filter by date for last 30 days, "__DateTimeOffset dateLimit = DateTimeOffset.Now.AddDays(-30)__" when I add dateLimit to db.Orders.Where(), the nullreferenceexception is thrown on dateLimit, as you can see, dateLimit use DateTimeOffset.Now to fill and NullReferenceException can't happen there. I opened a discussion at stackoverflow, there are more details. http://stackoverflow.com/questions/27071315/does-entityframework-monitor-variables-prior-to-its-declaration-and-use?noredirect=1#comment42656445_27071315

New Post: How to deply with automatic migration enabled?

$
0
0
I don't understand the concept of automatic migration.

Having set "AutomaticMigrationsEnabled = true;" in the Migrations.Configuration class I can't find the place where migration steps are stored.

How will Entity Framework recognize the current state of a production database and update it accordingly when, e.g., my console application is run at the customers' office?

Any information on this is very appreciated.

Thanks,
Axel

Commented Issue: Investigate impact of DBCC TRACEON [2590]

$
0
0
According to [this article](http://spaghettidba.com/2013/02/08/using-querytraceon-in-plan-guides/), there might be a potential permissions issue when a low-privileges account executes a query that uses a QUERYTRACEON option. For example:
```SQL
SELECT *
FROM [AdventureWorks2012].[Person].[Person]
OPTION (QUERYTRACEON 4199)
```
If the user doesn't have enough privileges then the following error will return from the server:
```
Msg 2571, Level 14, State 3, Line 1
User ‘guest’ does not have permission to run DBCC TRACEON.
```
This is worthy of investigation since [changeset 6f4a59148c5c](http://entityframework.codeplex.com/SourceControl/changeset/6f4a59148c5c980d42d61bcc594a2837a236ef6f) tried to fix workitem [2445](https://entityframework.codeplex.com/workitem/2445) by adding a QUERYTRACEON option to the process of discovering the store schema as a workaround given that SQL Server 2014 has a performance regression and this trace flag tells the engine to behave as SQL Server 2012 would for this query.

If this change affects users with low privileges negatively (meaning, they used to be able to obtain the store schema information but now can't) then we must address it as a compatibility issue.
Comments: FWIW, my informal testing indicates that this fix https://entityframework.codeplex.com/workitem/667 actually removes the requirement for the QUERYTRACEON option, due to the changes in that fix to the SQL statement to get the foreign keys. But unsure if the repro you did was done with the #667 fix included.

Created Unassigned: CF: [Required] / [MinLength] data annotations insufficient [2591]

$
0
0
To my knowledge, the __RequiredAttribute__ data annotation for string types only results in the corresponding database table column being created as NOT NULL.

I believe this is not sufficient. Moreover, it is in conflict with user interface layers, like MVC, which cannot reliably discern between an input being null or an empty string.

So I'd like to suggest to amend the behaviour of the __RequiredAttribute__ so that it will additionally create the following T-SQL CHECK constraint: __CHECK (LEN(LTRIM(RTRIM( {columnName} ))) > 0)__.

So an entity definition like the following:

```
public class MyEntity
{
public int Id;

[Required]
[Index(“UK_MyEntity_Name”, IsUnique= true)]
public string Name;
}
```

should result in the following DDL:

```
CREATE TABLE MyEntities
( Id INT CONSTRAINT PK_MyEntities PRIMARY KEY IDENTITY
, Name NVARCHAR(MAX) NOT NULL CONSTRAINT UK_MyEntity_Name UNIQUE CONSTRAINT CK_MyEntity_Name CHECK (LEN(LTRIM(RTRIM(Name))) > 0)
)
```

.

Similar for the __MinLengthAttribute__ data annotation. It should, too, add the following CHECK constraint: __CHECK(LEN( {columnName} ) > x )__.

So an entity definition like the following:

```
public class MyEntity
{
public int Id;

[MinLength(15)]
[Index(“UK_MyEntity_Name”, IsUnique= true)]
public string Name;
}
```

should result in the following DDL:

```
CREATE TABLE MyEntities
( Id INT CONSTRAINT PK_MyEntities PRIMARY KEY IDENTITY
, Name NVARCHAR(MAX) CONSTRAINT UK_MyEntity_Name UNIQUE CONSTRAINT CK_MyEntity_Name CHECK (LEN(Name) > 15)
)
```

.

Applying both attributes in conjunction should merge the generated CHECK constraint into one:

```
public class MyEntity
{
public int Id;

[Required]
[MinLength(15)]
[Index(“UK_MyEntity_Name”, IsUnique= true)]
public string Name;
}
```

should result in the following DDL:

```
CREATE TABLE MyEntities
( Id INT CONSTRAINT PK_MyEntities PRIMARY KEY IDENTITY
, Name NVARCHAR(MAX) NOT NULL CONSTRAINT UK_MyEntity_Name UNIQUE CONSTRAINT CK_MyEntity_Name CHECK (LEN(LTRIM(RTRIM(Name))) > 15)
)
```

.

__I'm not sure whether the LTRIM/RTRIM should by mandatory in above cases or optionally added by providing an additional constructor parameter to above data annotations.__

Edited Unassigned: [Required] / [MinLength] data annotations insufficient [2591]

$
0
0
To my knowledge, the __RequiredAttribute__ data annotation for string types only results in the corresponding database table column being created as NOT NULL.

I believe this is not sufficient. Moreover, it is in conflict with user interface layers, like MVC, which cannot reliably discern between an input being null or an empty string.

So I'd like to suggest to amend the behaviour of the __RequiredAttribute__ so that it will additionally create the following T-SQL CHECK constraint: __CHECK (LEN(LTRIM(RTRIM( {columnName} ))) > 0)__.

So an entity definition like the following:

```
public class MyEntity
{
public int Id;

[Required]
[Index(“UK_MyEntity_Name”, IsUnique= true)]
public string Name;
}
```

should result in the following DDL:

```
CREATE TABLE MyEntities
( Id INT CONSTRAINT PK_MyEntities PRIMARY KEY IDENTITY
, Name NVARCHAR(MAX) NOT NULL CONSTRAINT UK_MyEntity_Name UNIQUE CONSTRAINT CK_MyEntity_Name CHECK (LEN(LTRIM(RTRIM(Name))) > 0)
)
```

.

Similar for the __MinLengthAttribute__ data annotation. It should, too, add the following CHECK constraint: __CHECK(LEN( {columnName} ) > x )__.

So an entity definition like the following:

```
public class MyEntity
{
public int Id;

[MinLength(15)]
[Index(“UK_MyEntity_Name”, IsUnique= true)]
public string Name;
}
```

should result in the following DDL:

```
CREATE TABLE MyEntities
( Id INT CONSTRAINT PK_MyEntities PRIMARY KEY IDENTITY
, Name NVARCHAR(MAX) CONSTRAINT UK_MyEntity_Name UNIQUE CONSTRAINT CK_MyEntity_Name CHECK (LEN(Name) > 15)
)
```

.

Applying both attributes in conjunction should merge the generated CHECK constraint into one:

```
public class MyEntity
{
public int Id;

[Required]
[MinLength(15)]
[Index(“UK_MyEntity_Name”, IsUnique= true)]
public string Name;
}
```

should result in the following DDL:

```
CREATE TABLE MyEntities
( Id INT CONSTRAINT PK_MyEntities PRIMARY KEY IDENTITY
, Name NVARCHAR(MAX) NOT NULL CONSTRAINT UK_MyEntity_Name UNIQUE CONSTRAINT CK_MyEntity_Name CHECK (LEN(LTRIM(RTRIM(Name))) > 15)
)
```

.

__I'm not sure whether the LTRIM/RTRIM should by mandatory in above cases or optionally added by providing an additional constructor parameter to above data annotations.__

Created Unassigned: [Index]/[Unique] data annotation should be a class/table attribute [2592]

$
0
0
Currently, for a multi-column index, one has to repeat the index name for each __IndexAttribute__ data annotation over and over again. This requirement is rather error prone (in regard to typos) and it's clumsy.

Moreover, for a multi-column index, the requirement of providing ordinal numbers renders editing an EDM class cumbersome and error prone, too. One always has to make sure the ordinals are continuous and strictly monotonically increasing.

.

Just like the T-SQL syntax suggests, I'd suggest to apply the __IndexAttribute__ on class level.

This way you omit the clumsy name and ordinal requirement. Programmers would just give a comma-separated list of property names by means of an array of lambda expressions - and that's it:

```
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
public IndexAttribute(Expression<Func<TEntityType, TObject>> properties
,bool[] descending = null)
{...}
}
```

Which would result in using something similar to:

```
[Index(new {x.Name, x.Country}
,new [] {false, true})]
public class MyEntity
{
public int Id;
public string Name;
public string Country;
}
```

.

The original __IndexAttribute__, which is applied to properties, should be eased to mainly support single column indices by requiring merely the IsUnique constructor parameter:

```
[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple = false)]
public class IndexAttribute : Attribute
{
public IndexAttribute (bool isUnique)
{...}
}
```

.

This is also true for a unique key spanning more than a single column in contrast to a unique key spanning just one single column.

If you're going to introduce the __UniqueAttribute__ data annotation with EF7, i suggest to use the same semantics as the one I described above:

```
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = true)]
public class UniqueAttribute : Attribute
{
public UniqueAttribute(Expression<Func<TEntityType, TObject>> properties)
{...}
}
```

Which would result in using something similar to:

```
[Unique(new {x.Name, x.Country})]
public class MyEntity
{
public int Id;
public string Name;
public string Country;
}
```

The __UniqueAttribute__, applied to a property, should support only single column unique keys:

```
[AttributeUsageAttribute(AttributeTargets.Property, AllowMultiple = false)]
public class IndexAttribute : Attribute
{}
```

.

Both, index and unique key data annotations should derive an appropriate index name automatically.

Reviewed: EF 5.0.0 (ноя 25, 2014)

$
0
0
Rated 5 Stars (out of 5) - xfjsrtjtrsjsrtjtrjsrtja
Viewing all 10318 articles
Browse latest View live


Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>