¿Qué modelo de datos .NET me permite olvidarme de los ID?

I'd like to take advantage of .NET's data frameworks, but I'm a bit confused about how they work, and I'm not sure if what I want is possible. (I've done much of this with PHP frameworks, so I should hope .NET can do the same!) In short, I'd like my business logic to be database-agnostic, and in some sense, agnostic of the fact that it's a database at all.

Queries like this irritate me:

var productNames =
    from p in context.Products
    where seller.SellerID == mySeller.SellerID
    select p.Name;

Instead, I'd like to do:

var productNames =
    from p in context.Products
    where seller == mySeller
    select p.Name;

In essence, I want my business logic to not servicios sociales about the ID mappings. Partly, this is because in a few tables, IDs have real meaning. (Some of the tables I'm working with are imported from another application domain, and I need to be able to work with those IDs directly, but for my own types the IDs are incidental.)

It's a minor point in the example, but in general, I want to be able to work entirely in the world of objects and more or less forget about the realities of the underlying database. Is this just a matter of defining equivalence operators for my classes?

In summary: What .NET data framework gives me the cleanest database abstraction to the world of objects?

preguntado el 03 de mayo de 12 a las 17:05

how else would you únicamente identify one seller from another in your domain without an id or some other unique identifier? -

I was hoping to use IDs for comparison, but to define that relationship elsewhere so it's invisible to my business logic. -

2 Respuestas

If there is a relationship between Products and Sellers (I have no idea what seller is in your code examples), then EF let's you do p.Seller (or p.Sellers if there can be multiple sellers per product).

But that doesn't seem to help what you want to do. seller == mySeller is not at all clear. What determines equality? Normally, you have a primary key to establish equality. And so comparing IDs still makes sense. In addition, it is generally also much more efficient.

Otra opción es sobrecargar el == operator. This allows you to write a method that compares IDs, which is not visible to the user of the operator. However, this may or not work in your queries because it can't be converted to SQL.

contestado el 03 de mayo de 12 a las 18:05

Sure—but can I define that equivalence once in Seller instead of every single place where I look for that equivalence? - Enrique Merriam

I had just updated my answer. You can do that. But the database doesn't know about it. In cases where the query is being converted to SQL, it wouldn't work. - jonathan madera

I see. That's too bad. (I'm assuming the query would just pull all Products and compare the Seller objects locally?) - Enrique Merriam

You can do that. You can return all products, and then use something like ToList() to execute the query. Then, depending on exactly what you're doing, you could use C# constructs. But this seems horribly inefficient. - jonathan madera

If you are simply trying to compare objects without having to use properties, you can override Equivale in your classes. However this is a bad idea because it hides the logic of what is going on. I strongly advise against it

contestado el 03 de mayo de 12 a las 17:05

Can you elaborate as to why it's bad practice to define database objects as equal if they have the same ID? - Enrique Merriam

because if I do something such as seller.Name = "John" y luego hago un seller.Equals(mySeller), they have the same IDs so therefore its going to return true even though the objects are not identical. This is just one example - hielomand

+1. Operator == has a particular behavior expected by most people and just comparing IDs (especially for mutable objects) goes against expected behavior as icemanind points out. I.e. no one will be able to figure out why items are not updated in the database (all copies are equal all the time just due ID, aren't they?) or something similar if you implement such behavior. Note that if your classes are immutable it may be OK if you guarantee that IDs are as unique as objects themselves. - Alexéi Levenkov

While I still respect the answer, I find it perfectly appropriate for Equals or operator == to compare an ID type field of an object rather than every single instance field. For those objects equality is defined by the ID field; if two objects have the same ID and different values it's the creation/mutation of those objects that "wrong" rather than the equals method. Obviously this isn't applicable for all types, but I'd assert that it's at least sometimes appropriate. On a side note, you can make a separate method, other than equals, such as IDEqual. - Servir

Would it be incorrect to define == y Equals ¿diferentemente? == para la igualdad de referencia y Equals for ID equality? Can't I even just use ReferenceEquals when I want reference equality? - Enrique Merriam

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.